ashにbashスタイルの配列に移植する方法は?


12

少し前に、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
}

実際には40ほどのサービスが並んでいますが、この移行をできるだけ簡単でクリーンなものにしたいと考えています。bashisms を常に使用しています。今、私はスクリプトをよりポータブルにするタスクに困っています。

移植性の理由から、おそらく純粋なash解決策があればいいでしょう。しかし、私はbusybox自分の自由にかなり頑強なので、移植性を犠牲にするかもしれません。「クリーン」スクリプトもメトリックであるため、読みやすさが大幅に向上する場合にのみ。

この場合、ポータブルクリーンなソリューションは何でしょうか?

回答:


8

配列はであった前bashkshおよび他のシェル、通常の方法は、すべての要素を含む文字列上の要素(または任意の必要な逃げを最小限に抑える稀であったもの)のいずれかにした区切り文字を選択し、そして反復するましたその区切り文字で区切られます。シェルはデフォルトで空白文字によって「単語」をすでに分割しているため、通常は空白文字が最も便利な区切り文字の選択です(別のものに分割する場合は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

$services必要がありませ我々がいるのでここでは二重引用符で囲まれたいシェルは「言葉」に分割します。


3

ashには配列がありません。接近するのは位置パラメータだけなので、

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

for service in "$@"
do
   START $service
done

3

サービスのリストを一度だけ参照する必要がある場合は、ヒアドキュメントを使用できます。

while IFS= read -r service
do
   START "$service"
done << END
service1.service
service2.service
service3.service
END

リストではサービス名を引用符で"$service"囲まないでください(正当な理由がない限り、おそらく引用符で囲む必要があります)。サービス名をインデントしたい場合は、タブで名前をインデントする<<-代わりに<<インデントします。

while IFS= read -r service
do
   START "$service"
done <<- END
        service1.service
        service2.service
        service3.service
END
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.