2
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$
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
}
| improve this answer | |
\$\endgroup\$
  • \$\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 Mar 3 at 8:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.