Home > OS >  Printing bash command line args with $@ inline
Printing bash command line args with $@ inline

Time:10-06

I want to add verbosity to my bash function by printing the command that it will run. What is the best way to print all arguments $@ inline?

ggtest ()
{
    echo 'git grep -n $@ -- "src/tests/*"'

    git grep -n "$@" -- "src/tests/*";
}

So that I can see an output such as:

$ ggtest "models and views"
git grep -n "models and views" -- "src/tests/*"
...

CodePudding user response:

An overcomplicated version you can cut down to support only the specific shell releases you need support for:

ggtest ()
{
    # note the following explicitly exits if run in a shell w/o array support
    local -a cmd || return                    # declare a function-local array
    cmd=( git grep -n "$@" -- "src/tests/*" ) # store intended command in array

    # below here, we take a different approach based on running bash version
    case $BASH_VERSION in

      '') # no BASH_VERSION == we're running with a shell that's not bash at all
        set -x                                # enable trace logging
        : "${cmd[@]}"                         # run : with our array as arguments
        { set  x; } 2>/dev/null               # silently disable tracing
        ;;

      [1-4].*) # pre-5.0 bash does not support ${var@Q}; these logs are uglier
        { printf '%q ' "${cmd[@]}"; printf \n; } >&2 ;;

      *) # modern bash; shortest syntax, prettiest output
        printf '%s\n' "${cmd[*]@Q}" >&2;;
    esac
    "${cmd[@]}"                               # execute our array
}

Note that in current shell releases printf %q will use backslashes rather than quotes for escaping, so it would change ggtest "some string" to have some\ string in the logs; not the worst thing in the word, but it's less pretty than ${array[*]@Q}'s representation

  • Related