On Sunday, July 29, 2012 03:23:29 PM Jason Vas Dias wrote: > Good day Chet, list - > I'm concerned about the difference in output of these functions with > the example input > given on the '$' prefixed line below (with 4.2.29(2)-release > (x86_64-unknown-linux-gnu)): > > function count_args { v=($@); echo ${#v[@]}; } > > function count_colons { IFS=':' ; v=($@); echo ${#v[@]}; } > > $ echo $(count_args 1 2 3\ 4) $(count_colons 1:2:3\:4) > 3 4 > > It appears to be impossible for an item delimited by 'X' to contain > an escaped 'X' ('\X') if 'X' is not > a standard delimiter (' ', '<TAB>') . Quoting doesn't seem to help either: > > $ echo $(count_args 1 2 3\ 4) $(count_colons 1:2:3':4') > 3 4 > > To me, this appears to be a bug. > > But I bet you're going to tell me it is a feature ? > Please explain.
Bash doesn't re-parse the results of expansions for quotes or escaping. When you expand something unquoted, the entire result is always subject to word-splitting. In the case of `count_args 1 2 3\ 4', you are passing 3 arguments. The backslash is not the result of expansion , so it gets treated as escaping a space. Note this is because bash is pass-by-value, this escaping/expansion is processed prior to calling the function. In the case of `count_colons 1:2:3\:4', you are passing one argument. The shell strips away the backslash when the function is called (just as it did in the first example), so the argument being passed is actually '1:2:3:4' $ printf '%s\n' 1:2:3\:4 1:2:3:4 If you wanted to pass the backslash, you would have to either quote the argument, or use \\. However in either case, you're going to have 4 arguments, because as previously stated, escape characters resulting from expansions are not treated as escapes. $ f() { IFS=: local -a 'v=( $@ )'; printf '<%s> ' "${v[@]}"; echo; }; f 1:2:3\:4 <1> <2> <3> <4> $ f() { IFS=: local -a 'v=( $@ )'; printf '<%s> ' "${v[@]}"; echo; }; f 1:2:3\\:4 <1> <2> <3\> <4> See also my answer to this recent question: http://superuser.com/a/454564/78905 -- Dan Douglas
signature.asc
Description: This is a digitally signed message part.