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