Posted Dec 8, 2011 22:41 UTC (Thu) by mathstuf (subscriber, #69389)
[Link]
To support *arbitrary* [NUL-terminated] strings in shell, you have to, AFAIK, do the following (to avoid arbitrary execution, get the exact backslash count, and more):
> for x in $( seq 1 ${#var} ); do
> echo -n "${var[$x]}"
> done
Granted, most of the time you don't need this (who puts 7 backslashes in a row? Well...tr might make sense with that many backslashes as an argument), but it needs to be copied verbatim every time unless you want to do another level of escaping passing it to a function.
Of course, if there's a shorter way, I'd be thrilled to know it :) .
Evolution of shells in Linux (developerWorks)
Posted Dec 8, 2011 22:51 UTC (Thu) by quotemstr (subscriber, #45331)
[Link]
You don't need to do any of that.
printf '%s' "$bar" is sufficient. The value of bar isn't expanded or interpreted.
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 9:39 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
That code doesn't make sense. You take the length of the first string in the array named "var", and then, for x from 1 to said length print the xth element of the array.
If all you wanted to do is print the elements of an array, you can do that with echo "${var[@]}". Well, unless something in ${var[@]} starts with a dash...
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 18:07 UTC (Fri) by mathstuf (subscriber, #69389)
[Link]
It's a string, not an array (indexing strings works here in bash). The idea is to avoid creating escape sequences that may appear when var is blindly expanded. Of course, the printf command given is much more succint and cleaner.
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 19:31 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
> It's a string, not an array (indexing strings works here in bash).
It certainly doesn't work with the syntax you've shown, as that is the syntax for array subscription.
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 20:09 UTC (Fri) by nybble41 (subscriber, #55106)
[Link]
Technically it *will* work, but only because the value of the variable is output in the first iteration of the loop, and the following iterations have no effect (${var[1..N]} are empty). I.e., aside from the obvious inefficiency, the entire loop is equivalent to:
echo -n "$var"
To work as intended the variable reference would need to use substring syntax, "${var:$x:1}", rather than the array syntax "${var[$x]}". However, it is sufficient to place the variable in double-quotes, which (in bash) causes the value to be output verbatim, with no further quoting, expansion, or splitting.
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 20:13 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
> Technically it *will* work, but only because the value of the variable is output in the first iteration of the loop,
No, the loop starts at 1 instead of 0.
Evolution of shells in Linux (developerWorks)
Posted Dec 9, 2011 20:25 UTC (Fri) by nybble41 (subscriber, #55106)
[Link]
Hm. You're right, which is strange since both arrays and characters are zero-indexed (except for $@). Perhaps that loop was written for a different shell entirely? It's certainly not necessary in reasonably modern implementations (i.e. within the last decade) of bash.
Evolution of shells in Linux (developerWorks)
Posted Dec 10, 2011 3:34 UTC (Sat) by mathstuf (subscriber, #69389)
[Link]
Nope, I was a typo. Somehow I missed that it just printed something on the first iteration, and nothing on the rest... Not sure how I forgot about printf either.