シェルスクリプトを実行すると、sh -c が正しい出力を取得できません。

シェルスクリプトを実行すると、sh -c が正しい出力を取得できません。

シェルの配列からデータを取得するために繰り返し、
次の内容を含むシェルファイルからデータを実行すると機能します。

arr=(1 2 3 4 5)  
for var in ${arr[@]};  
do  
    echo $var  
done

sh -cしかし、以下のように使用すると出力はありません。

sh -c "arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done"

答え1

問題はを使用していますsh -c "..."。ご覧ください。@gilsの答え詳細については。

さらに進むsh(参照POSIX sh)は配列をサポートしません(厳密に言えば、配列は1つだけなので、$@)、サポートされているシステムの他のシェルまたは別の配列を呼び出すbash必要zshがありますksh

bash -c 'arr=(1 2 3 4 5);for var in "${arr[@]}";do echo "$var"; done'

${arr[@]}また、逆参照時にミスをしたことに注意してください。実際にfor var in "${arr[@]}"これを変更する必要があります。引用符のない変数で分割+globを呼び出すことは、多くのセキュリティ脆弱性の原因です。

POSIX shを使用するには、次のものを使用できます。$@:

set -- 1 2 3 4 5
for var do
  printf '%s\n' "$var"
done

答え2

問題は、誤った引用タイプを使用していることです。シェルは二重引用符内に変数を挿入するため、変数参照は実行中のシェルによって挿入されますsh -c "…"。シェルが変数の名前を指定または定義しないと仮定すると、パラメータarrは次のようになります。varsh -c

arr=(1 2 3 4 5);for var in ;do echo ;done

配列認識シェルの場合、shこれは完全に有効なコードですが、何もしません。

リテラル文字列をコマンドに渡すには、単一引用符を使用します。一重引用符内のすべての文字は文字通り解釈されるため、一重引用符を除く文字列内の任意の文字を使用できます。 (一重引用符が必要な場合4桁のシーケンスでエスケープします。'\''.)

sh -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

すべての実装が配列をサポートしているわけではありませんsh。配列が必要な場合は、それをサポートするシェルを明示的に呼び出す必要があります。

ksh -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

または

bash -c 'arr=(1 2 3 4 5);for var in ${arr[@]};do echo $var;done'

関連情報