9

I am probably just having a brain fart, but I can not for the life of me figure out how to loop through an array in shell script, not bash. Im sure the answer is on stackoverflow somewhere already, but I can not find a method of doing so without using bash. For my embedded target system bash is not currently an option. Here is an example of what I am attempting to do and the error that is returned.

#!/bin/sh

enable0=1
enable1=1

port=0
while [ ${port} -lt 2 ]; do
    if [ ${enable${port}} -eq 1 ]
        then
        # do some stuff
    fi

    port=$((port + 1))
done

Whenever I run this script the error "Bad substitution" is returned for line with the if statement. If you guys have any ideas I would greatly appreciate it. Thanks!

5
  • Which distro? Or, which shell is /bin/sh in your embedded system? Commented Sep 29, 2014 at 2:33
  • I will look in a moment to make sure, but it should be the same shell that is used in debian. Commented Sep 29, 2014 at 2:36
  • 1
    The if line has unbalanced brackets and a space between the - and the eq so I would fix those problems first. Commented Sep 29, 2014 at 2:40
  • 1
    Actually I was incorrect. The system points to busybox, which then turns around and points to a variation of the ash. Sorry about that. Still new to this platform Commented Sep 29, 2014 at 2:42
  • Oops, good catch Ray! That was a miss type only on stackoverflow, not in my actually script. Commented Sep 29, 2014 at 2:45

4 Answers 4

15
a="abc 123 def"

set -- $a
while [ -n "$1" ]; do
    echo $1
    shift
done

Output via busybox 1.27.2 ash:

abc
123
def
Sign up to request clarification or add additional context in comments.

1 Comment

While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
6

BusyBox provides ash which does not directly provide array support. You could use eval and something like,

#!/bin/busybox sh
enable0=0
enable1=1

for index in 0 1 ; do
  eval assign="\$enable$index"
  if [ $assign == 1 ]; then
    echo "enable$index is enabled"
  else
    echo "enable$index is disabled"
  fi
done

Comments

2

It's best not to use eval unless there is no other alternative. (The recent spate of bash exploits is due to the shell internally evaling the contents of environment variables without verifying their contents first). In this case, you seem to be in complete control for the variables involved, but you can iterate over the variable values without using eval.

#!/bin/sh

enable0=1
enable1=1

for port_enabled in "$enable0" "$enable1"; do
    if [ "$port_enabled" -eq 1 ]; then
        # do some stuff
    fi
done

Comments

2

One could use positional parameters for that...

http://pubs.opengroup.org/onlinepubs/009696799/utilities/set.html

#!/bin/sh

enable0=0
enable1=1

set -- $enable0 $enable1

for index in 0 1; do
    [ "$1" -eq 1 ] && echo "$1 is enabled." || echo "$1 is disabled."
    shift
done

Running on busybox:

~ $ ./test.sh 
0 is disabled.
1 is enabled.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.