What I'm doing wrong?
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq 1 ${#list[@]}` ; do echo $i ; done "
it should return:
1
2
3
instead of:
/bin/sh: -c: line 1: syntax error near unexpected token `2'
/bin/sh: -c: line 1: `2'
In your original code, the double-quoted string you pass to /bin/sh
is processed by the shell before calling sh
. In particular, both the command substitution involving seq
and the parameter $i
are expanded. As a result, you get the following (you can confirm by calling set -x
before running your code):
for i in 1
2
3 ; do echo ; done
The newline following 1 is treated as a termination of the sequence that for
will iterate over. At this point, sh
will expect the keyword do
, but it instead sees 2
.
One way to fix this, assuming you really need to pass a string to another instance of the shell, is to tell seq
to use a different separator (such as a space). You'll need to escape
the dollar sign in $i
as well so that it is evaluated by the subshell, not the current shell.
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq -s' ' 1 ${#list[@]}` ; do echo \$i ; done "
This will work with sh
, because the subshell does not see the array, which it would not understand anyway. sudo_O provides a different answer, which involves protecting the entire string passed to sh
, and including the definition of list
in that string so that it is visible in the subshell. Note that your sh
must be a shell such as bash
, since POSIX sh
does not support arrays, as pointed out by jordanm.