Here-Document

使用 heredoc 遍歷命令列表

  • March 19, 2022

這工作正常:

$ 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, not read


另一件事:片段done < <(cat << EOF可以簡化為done << EOF(注意此更改需要)從程式碼末尾刪除)。

引用自:https://unix.stackexchange.com/questions/696045