Shell

如何將輸出重定向與 here-documents 和 cat 結合使用?

  • December 3, 2021

假設我有一個腳本,我想通過管道傳輸到另一個命令或重定向到一個文件(管道傳輸sh到範例)。假設我正在使用 bash。

我可以使用echo

echo "touch somefile
echo foo > somefile" | sh

我也可以使用以下方法做幾乎相同的事情cat

cat << EOF
touch somefile
echo foo > somefile
EOF

但是如果我用“EOF | sh”替換“EOF”,它只會認為它是heredoc的一部分。

我怎樣才能使它cat從標準輸入輸出文本,然後將其通過管道傳輸到任意位置?

有多種方法可以做到這一點。最簡單的大概是這樣的:

cat <<EOF | sh
touch somefile
echo foo > somefile
EOF

另一個,在我看來這是更好的語法:

(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh

這也有效,但沒有子外殼:

{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh

更多變體:

cat <<EOF |
touch somefile
echo foo > somefile
EOF
 sh

或者:

{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF

順便說一句,我希望cat在你的問題中使用的是其他東西的佔位符。如果沒有,把它拿出來,像這樣:

sh <<EOF
touch somefile
echo foo > somefile
EOF

這可以簡化為:

sh -c 'touch somefile; echo foo > somefile'

或者:

sh -c 'touch somefile
echo foo > somefile'

重定向輸出而不是管道

sh >out <<EOF
touch somefile
echo foo > somefile
EOF

cat用於獲得等價於echo test > out

cat >out <<EOF
test
EOF

多個此處文件

( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2

這將產生輸出:

hi
---
there

這是發生了什麼:

  • shell 看到( ... )並在子shell 中執行封閉的命令。
  • cat 和 echo 很簡單。說要使用cat <&3從 fd 3 重定向的文件描述符 (fd) 0 (stdin) 執行 cat;換句話說,從 fd 3 中提取輸入。
  • (...)啟動之前,shell 會看到兩個 here 文件重定向並將 fd 0 ( <<EOF) 和 fd 3 ( 3<<EOF2) 替換為管道的讀取端
  • 啟動初始命令後,shell 會讀取其標準輸入,直到到達 EOF 並將其發送到第一個管道的寫入端
  • 接下來,它對 EOF2 和第二個管道的寫入端執行相同的操作

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