これはうまくいきます:
$ 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行ずつ評価すると、複数行のコマンドを評価することはできません。
指定した文字列を実際に使用してこれを使用して作業をしたくない場合<< EOF
(IFS= read
何をしているのかを知っている場合)は、スクリプトに直接コードを書くだけです。結局のところ、計算を実行するためにシェルはスクリプトを解釈したいと思いますecho "1" > ~/Desktop/in/foo
。他のシェルプロセスも必要ありません。ここでは文書は必要ありません。
他のシェルプロセスのコード前処理は意味があるかもしれませんが(場合によっては注意してください)、eg bash << EOF
、notを使用する必要がありますread
。
別の点:コードスニペットをdone < <(cat << EOF
単純化することができますdone << EOF
(この変更は)
コードの最後から削除する必要があります)。