2

I loop to get data from array in shell ,
It works when I execute it in a shell file, with this content:

arr=(1 2 3 4 5)  
for var in ${arr[@]};  
do  
    echo $var  
done

But there isn't any output when I use sh -c like below:

sh -c "arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done"
1
  • Note that printf will iterate if you provide more values than placeholders. Your for loop can be written like this: bash -c 'arr=(1 2 3 4 5); printf "%s\n" "${arr[@]}"' Sep 10, 2015 at 13:29

2 Answers 2

6

Your problem is using sh -c "...", see @Gilles's answer for more details.

Further more, sh (refer to POSIX sh) does not support array (strictly speaking, it has only one array, $@), you need to call other shells on your system, which support array like bash, zsh or ksh.

bash -c 'arr=(1 2 3 4 5);for var in "${arr[@]}";do echo "$var"; done'

Also note that you have a mistake when leaving ${arr[@]} un-quote, actually you need for var in "${arr[@]}" instead. Invoking variable without quotes calling split+glob and is source of many security implication.

To play with POSIX sh, you can use $@:

set -- 1 2 3 4 5
for var do
  printf '%s\n' "$var"
done
7
  • I'd also recommend to attach shebang en.wikipedia.org/wiki/Shebang_%28Unix%29 at the beggining of EACH script. Sep 10, 2015 at 10:49
  • 2
    @MateuszPacek: The OP calling sh -c inline script instead of creating a shell script. the shebang didn't help in this case.
    – cuonglm
    Sep 10, 2015 at 10:51
  • @ccuonglm yes, that's true. But when you got script in file it's easier to exec it inline if you know what kind of shell implementation you used to use. Sep 10, 2015 at 10:55
  • 2
    @c4f4t0r this works only if your sh isn't really sh but is actually bash, zsh, or ksh in poor disguise. You shouldn't really use bash features with the shell invoked as sh as one day it may break (consider Debian with sh a symlink to dash rather than bash). Sep 10, 2015 at 13:05
  • 1
    @c4f4t0r, still, avoid bad practices: use the most precise interpreter for your code. Sep 10, 2015 at 13:28
2

The problem is that you used the wrong type of quotes. Shells interpolate variables inside double quotes, so the variable references were interpolated by the shell in which you ran sh -c "…". Assuming that this shell didn't have variables named arr or var defined, the argument to sh -c was

arr=(1 2 3 4 5);for var in ;do echo ;done

If sh is a shell that supports arrays, this is perfectly valid code, that happens to do nothing.

To pass a literal string to a command, use single quotes. All characters inside single quotes are interpreted literally, so you can use every character except a single quote in the string. (If you need a single quote, escape it as the four-character sequence '\''.)

sh -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

Beware that not all implementations of sh support arrays. If you need arrays, you should explicitly invoke a shell that supports them.

ksh -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

or

bash -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .