# POSIX shell function to “dump” all given arguments

My today's idea was to create a POSIX shell function to dump all given arguments, typical use would be to call it from a fucntion, where you already know some arguments are not well set (empty; not integer) and this way you can inspect all given arguments in one go. It reminds me of a PHP var_dump function. :) Would anyone be able to find weak spots in there, all input is welcome.

#!/bin/sh

dump_arguments ()
# string function - prints arguments (position and content)
# indicates empty arguments and integer numbers
{
printf '%b' "dump_arguments()\\n----------------\\n$# arguments are being inspected" [$# -gt 0 ] && { printf ':\n'; i=1; } || printf '.\n'
while [ $# -gt 0 ]; do printf '%s' "[$i]: '$1'" [ -z "$1" ] && printf ' (empty)'
[ "$1" -eq "$1" ] 2> /dev/null && printf ' (integer)'
printf '\n'
shift 1
i=$((i+1)) done } >&2 # inside some function you would call it like this dump_arguments "$@"

# but to only try it out, you can call it directly
dump_arguments '1' '' 5



printf '%b' "dump_arguments()\\n----------------\\n$# arguments are being inspected"  We could make that easier to read by making each line a separate argument, and ending the line properly (rather than requiring a separate command): punct=.${1+false} true || punct=:
printf '%s\n'                                       \
'dump_arguments()'                           \
'----------------'                           \
"$# arguments are being inspected$punct"


It seems odd to use %s here:

    printf '%s' "[$i]: '$1'"


Why not use the format string more clearly? And this allows us to modify to use %q if we have a suitable printf:

    printf "[%d]: '%s'" "$i" "$1"


Perhaps even combine the type into a single print:

    type=
[ -z "$1" ] && type=' (empty)' [ "$1" -eq "$1" ] 2>/dev/null && type=' (integer)' printf "[%d]: '%s'%s\n" "$i" "$1" "$type"


Is it intentional that strings such as ' 5' (with leading and/or trailing spaces) are counted as integers?

    shift 1


Normally written simply as

    shift


That said, I think it's more natural to iterate over arguments using a for loop instead.

} >&2


That's surprising, as the output isn't an error, but expected when calling the function. It should be up to the caller to choose where stream 1 goes.

# Modified code

#!/bin/sh

dump_arguments()
# string function - prints arguments (position and content)
# indicates empty arguments and integer numbers
{
punct=${1+:} printf '%s\n' \ 'dump_arguments()' \ '----------------' \ "$# arguments are being inspected${punct:-.}" i=1 for v do if [ -z "$v" ]
then type=' (empty)'
elif [ "$v" -eq "$v" ] 2>/dev/null
then type=' (integer)'
else type=
fi
printf "[%d]: '%s'%s\n" \
"$i" "$v" "$type" i=$((i+1))
done
}

• No, I just didn't show that line. There's no harm in defining it regardless, so I just wrote it before the loop. I'll edit to show my full modified version. – Toby Speight Mar 3 '20 at 8:04