Wednesday, August 2, 2017

Shell argument handling vs

Shell argument handling vs


I never can recall the difference between $* and $@ in scripts so heres a little experiment which should help, hope that I remember this time :-)

First of all there is this little script to show all args of a script, call it args.sh

#!/bin/sh cnt=0 for arg do cnt=`expr $cnt + 1` printf "arg$cnt = $arg " done 

args.sh 1 "2 3" "4 "5" 6" 
will show
arg1 = 1 arg2 = 2 3 arg3 = 4 "5" 6 
i.e. the script counts and shows three arguments.

In order to test how $* and $@ are passed to sub processes there is a little script test.sh in four variations, once pure and once surrounded by quotes:
#!/bin/sh args.sh $*
#!/bin/sh args.sh "$*"
#!/bin/sh args.sh $@
#!/bin/sh args.sh "$@"
test.sh 1 "2 3" "4 "5" 6" 
will lead to
arg1 = 1 arg2 = 2 arg3 = 3 arg4 = 4 arg5 = "5" arg6 = 6 
arg1 = 1 2 3 4 "5" 6 
arg1 = 1 arg2 = 2 arg3 = 3 arg4 = 4 arg5 = "5" arg6 = 6 

arg1 = 1 arg2 = 2 3 arg3 = 4 "5" 6 
i.e. only the last invocation does what we want: it keeps and forwards the original arguments.

All other invocations either split the arguments by space or concatenate all arguments into one big single argument.

Another little trap I fell into: when trying to save the arguments in a variable neither invocation is successful

#!/bin/sh a=$* b="$*" c=$@ d="$@" args.sh $a args.sh $b args.sh $c args.sh $d 
#!/bin/sh a=$* b="$*" c=$@ d="$@" args.sh "$a" args.sh "$b" args.sh "$c" args.sh "$d" 
all lead to the complete split all lead to a single argument
arg1 = 1 arg2 = 2 arg3 = 3 arg4 = 4 arg5 = "5" arg6 = 6 

arg1 = 1 2 3 4 "5" 6 

This is all in Bourne shell (if in doubt).

download file now

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.