Shell脚本中的数组,非Bash

8

我可能只是脑子一片空白,但我无法想出如何在shell脚本中循环遍历数组,而不使用bash。我相信答案已经在stackoverflow上了,但我找不到一种方法可以不使用bash来实现。对于我的嵌入式目标系统,当前不支持bash。这里是我尝试做的事情和返回的错误示例。

#!/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

每当我运行这个脚本时,if语句所在的那行会返回错误“Bad substitution”。如果你们有任何想法,我将非常感激。谢谢!

哪个发行版?或者说,在你的嵌入式系统中,/bin/sh 是哪个 shell? - Elliott Frisch
我一会儿看一下确保,但应该是在 Debian 中使用的相同 shell。 - TheLastFuzzy
1
if 行有不平衡的括号和 -eq 之间有一个空格,所以我会先修复这些问题。 - Ray Toal
1
实际上我错了。系统指向busybox,然后又指向ash的一个变体。对此感到抱歉。我还是对这个平台比较新。 - TheLastFuzzy
哎呀,好眼力 Ray!那只是在 stackoverflow 上的一个打错字,而不是我的实际脚本中的。 - TheLastFuzzy
4个回答

14
a="abc 123 def"

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

通过busybox 1.27.2的ash输出:

abc
123
def

5
虽然这段代码片段可以解决问题,但是包括说明真的有助于提高您帖子的质量。请记住,您正在为未来的读者回答问题,而那些人可能不知道您的代码建议的原因。 - J. Chomel

6

BusyBox提供了ash,但它并不直接支持数组。您可以使用eval和类似以下内容的方法:

#!/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

2

可以使用位置参数来实现这个目的...

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

在busybox上运行:

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

1
最好不要使用eval,除非没有其他选择。(最近一系列的bash漏洞是由于shell在未验证环境变量内容的情况下内部eval其内容所致)。在这种情况下,看起来您完全控制所涉及的变量,但您可以在不使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接