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
1 Answer 1
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
}
-
\$\begingroup\$ 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. \$\endgroup\$Toby Speight– Toby Speight2020年03月03日 08:04:22 +00:00Commented Mar 3, 2020 at 8:04
[ "1ドル" -eq "1ドル" ]
, in yash and zsh, since how they handle the algebraic checks is a bit different from your regular shells like bash. \$\endgroup\$[ "1 " -eq "1 " ]
would return with exit status 0 without any warning or error messages. \$\endgroup\$