使用 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
執行
eval 'echo "1" > ~/Desktop/in/foo'
時,shell 會刪除單引號,然後eval
計算echo "1" > ~/Desktop/in/foo
.當您執行時
eval "$_cmd"
(在更新前的程式碼中),shell 會展開$_cmd
並刪除雙引號,然後eval
計算'echo "1" > ~/Desktop/in/foo'
. 注意單引號。您不想eval
看到它們,請將它們從此處的文件中刪除。在您更新的程式碼中,您可能想要
eval
評估echo "1" > ~/Desktop/in/'foo (bis)'
,因此請使用此處文件中的這一行。好吧,“確切”通常不是正確的詞。通常
<< EOF
(與 eg 相對<< 'EOF'
)擴展了此處文件中的變數和其他一些內容(您的範例中沒有,但通常這是它的工作原理)。然後IFS= read _cmd
不是IFS= read -r _cmd
。最後eval
得到一個字元串,它不一定是您使用的確切字元串。逐行評估使得評估多行命令變得不可能。
除非您真的想依賴於您提供的字元串(
<< EOF
並且IFS= read
您知道自己在做什麼),否則只需直接在腳本中編寫程式碼即可。畢竟,您希望解釋腳本的 shell 評估echo "1" > ~/Desktop/in/foo
. 它甚至不是你想要一些其他的 shell 程序。這裡不需要這裡的文件。我想另一個shell程序的預處理程式碼可能有意義(在某些情況下並且當你小心時),但是你應該使用 eg
bash << EOF
, notread
。另一件事:片段
done < <(cat << EOF
可以簡化為done << EOF
(注意此更改需要)
從程式碼末尾刪除)。