私が間違っていることは何ですか?
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq 1 ${#list[@]}` ; do echo $i ; done "
返されるはずです:
1
2
3
それ以外の:
/bin/sh: -c: line 1: syntax error near unexpected token `2'
/bin/sh: -c: line 1: `2'
@chepnerが正しい答えをくれました。
ちなみに、このようにコマンドを短くすることもできます (それ以上のシェルは必要ありません)。
unset list
list=("A" "B" "C")
for i in `seq 1 ${#list[@]}` ; do echo $i ; done
元のコードでは、渡す二重引用符で囲まれた文字列は/bin/sh
、 を呼び出す前にシェルによって処理されますsh
。特に、関連するコマンド置換seq
とパラメーターの$i
両方が拡張されます。その結果、次のようになります (set -x
コードを実行する前に呼び出すことで確認できます)。
for i in 1
2
3 ; do echo ; done
1 に続く改行は、繰り返されるシーケンスの終了として扱われますfor
。この時点で、sh
はキーワード を予期しますdo
が、代わりに を参照します2
。
これを修正する 1 つの方法は、シェルの別のインスタンスに文字列を渡す必要があると仮定してseq
、別の区切り記号 (スペースなど) を使用するように指示することです。$i
現在のシェルではなく、サブシェルによって評価されるように、ドル記号もエスケープする必要があります。
unset list
list=("A" "B" "C")
/bin/sh -c "for i in `seq -s' ' 1 ${#list[@]}` ; do echo \$i ; done "
sh
サブシェルはとにかく理解できない配列を認識しないため、これは で機能します。sudo_O は別の答えを提供します。これには、に渡される文字列全体を保護し、その文字列sh
に の定義を含めてlist
、サブシェルで表示できるようにする必要があります。jordanm で指摘されているように、POSIXは配列をサポートしていないため、sh
などのシェルでなければならないことに注意してください。bash
sh
サブシェルを生成するときに配列list
は定義されないため、長さはありません。
for i in `seq 1 ${#list[@]}`
のように見える:
for i in seq 1 0
見る:
$ sh -c 'echo ${#list[@]}'
0
出力がseq 1 0
生成されないため、結果が表示されません。
list
現在のシェルで各値を設定して出力します。
$ list=("A" "B" "C")
$ for i in `seq 1 ${#list[@]}`;do echo $i;done
1
2
3
list
または、サブシェルで を定義します。
$ sh -c 'list=("A" "B" "C");for i in `seq 1 ${#list[@]}`;do echo $i;done'
1
2
3