Heredocを使用してコマンドリストを繰り返す

Heredocを使用してコマンドリストを繰り返す

これはうまくいきます:

$ eval 'echo "1" > ~/Desktop/in/foo'

しかし、これではありません:

$ while IFS= read _cmd; do eval "$_cmd"; done < <(cat << EOF
'echo "1" > ~/Desktop/in/foo'
'echo "2" > ~/Desktop/in/bar'
EOF
)
bash: echo "1" > ~/Desktop/in/foo: No such file or directory
bash: echo "2" > ~/Desktop/in/bar: No such file or directory

どうすれば修正できますか?


修正する

提案されているように一重引用符を削除すると機能しますが、このバリアントでは機能しません(一重引用符で囲まれたファイル名にも当てはまります)。

$ while IFS= read _cmd; do eval "$_cmd"; done < <(cat << EOF 
echo "1" > ~/Desktop/in/foo (bis)
echo "2" > ~/Desktop/in/bar
EOF
)

提供されたソリューションと一緒に:

"$SHELL" << EOF
echo "1" > ~/Desktop/in/'foo (bis)'
echo "2" > ~/Desktop/in/bar
EOF

答え1

を実行すると、eval 'echo "1" > ~/Desktop/in/foo'シェルは一重引用符を削除してからeval評価しますecho "1" > ~/Desktop/in/foo

eval "$_cmd"更新前のコードで実行すると、シェルは$_cmd二重引用符を展開して削除し、一重引用符をeval評価します'echo "1" > ~/Desktop/in/foo'。その項目を見たくない場合は、evalこちらの記事から削除してください。

更新されたコードでeval評価できるので、echo "1" > ~/Desktop/in/'foo (bis)'こちらの記事のこの行を使用してください。


まあ、「正しい」は一般的に正しい言葉ではありません。一般的に<< EOF(例えば反対<< 'EOF')、ここのドキュメントの変数といくつかの他のものを拡張します(あなたの例ではありませんが、それは一般的にはうまくいきます)。それでIFS= read _cmdはないIFS= read -r _cmd。最後にeval文字列を取得します。必ずしもそうする必要はありません。精密使用する文字列です。

1行ずつ評価すると、複数行のコマンドを評価することはできません。

指定した文字列を実際に使用してこれを使用して作業をしたくない場合<< EOFIFS= read何をしているのかを知っている場合)は、スクリプトに直接コードを書くだけです。結局のところ、計算を実行するためにシェルはスクリプトを解釈したいと思いますecho "1" > ~/Desktop/in/foo。他のシェルプロセスも必要ありません。ここでは文書は必要ありません。

他のシェルプロセスのコード前処理は意味があるかもしれませんが(場合によっては注意してください)、eg bash << EOF、notを使用する必要がありますread


別の点:コードスニペットをdone < <(cat << EOF単純化することができますdone << EOF(この変更は)コードの最後から削除する必要があります)。

関連情報