如何将 bash 样式的数组移植到 ash?

met*_*ing 17 shell bash array ash

前段时间我写了一个 bash 脚本,现在应该能够在ash.

bash它是这样的:

services=( "service1.service"
           "service2.service"                                       
           "service3.service" )  

for service in "${services[@]}"
do
   START $service                   
done

START()
{
   echo "Starting "$1
   systemctl start $1
}
Run Code Online (Sandbox Code Playgroud)

实际上,阵列中大约有 40 个服务,我想让这种转换尽可能轻松和干净。一直在使用bashisms。现在,我正忙于使脚本更具可移植性的任务。

出于可移植性的原因,拥有一个纯粹的ash解决方案可能会很好。但是由于我有一个非常强大的功能busybox,我可能会牺牲一些便携性。只有在可读性大大提高的情况下,因为“干净”的脚本也是一个指标。

在这种情况下,什么是便携式干净的解决方案?

cas*_*cas 10

在数组出现在bash,ksh和其他 shell 之前,通常的方法是选择一个不在任何元素中的分隔符(或者一个不常见的以最小化任何所需转义的分隔符),并遍历包含所有元素的字符串,由该分隔符分隔。空格通常是最方便的分隔符选择,因为默认情况下,shell 已经按空格拆分“单词”(如果您希望它拆分为不同的内容,可以设置 IFS)。

例如:

# backslash-escape any non-delimiter whitespace and all other characters that
# have special meaning to the shell, e.g. globs, parenthesis, ampersands, etc.
services='service1.service service2.service service3.service'

for s in $services ; do  # NOTE: do not double-quote $services here.
  START "$s"
done
Run Code Online (Sandbox Code Playgroud)

$services应该不是在这里,因为我们的双引号外壳将它拆分成“单词”。


gle*_*man 5

ash 没有数组。唯一接近的是位置参数,所以你可以这样做

set -- "service1.service" \
       "service2.service" \
       "service3.service"

for service in "$@"
do
   START $service
done
Run Code Online (Sandbox Code Playgroud)