Bash
為什麼 cat 命令重定向新文件會立即執行?
我想生成一個可以稍後呼叫的 bash 文件,像這樣
cat <<-SCRIPT >test-$$ #!/bin/bash osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release) if [ "$osType" = ...] then ... fi exit SCRIPT
當我調試時,grep 命令總是以正確的方式執行,為什麼?也嘗試使用 awk 相同的錯誤
但如果我這樣做
cat <<-SCRIPT >test-$$ #!/bin/bash rpm -q somepackage > test-$$ rm test-$$-lock exit SCRIPT
我沒有看到 rpm 命令以正確的方式執行?也做測試——
$$ and test- $$-lock 將具有相同的 $$?
類似 here-doc 的
<<-SCRIPT
行為就像一個雙引號字元串,因為在其中處理了擴展。為防止這種情況,請引用分隔符:$ cat <<EOF 1+1 = $((1+1)) EOF 1+1 = 2
對比
$ cat <<'EOF' 1+1 = $((1+1)) EOF 1+1 = $((1+1))
所以在這裡:
cat <<-SCRIPT >test-$$ ... osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)
該
grep
命令在一個命令替換中,因為SCRIPT
沒有被引用,所以它被處理,所以它在使用 here-doc 時執行。另一方面,這裡:
cat <<-SCRIPT >test-$$ #!/bin/bash rpm -q somepackage > test-$$ rm test-$$-lock exit SCRIPT
沒有命令替換,所以沒有命令執行。該
rpm -q somepackage
部分只是文本。但是,如果使用不帶引號的分隔符,$$
則 here-doc 內部將立即擴展為與輸出文件名稱中使用的值相同的值。也就是說,如果目前 shell 的 PID 為 1234,則該cat
命令將創建test-1234
包含該行的rpm -q somepackage > test-1234
.使用帶引號的分隔符,
$$
將保持原樣,結果將是名為test-1234
contains 的文件rpm -q somepackage > test-$$
。如果您現在test-1234
作為腳本執行,那麼$$
將會擴展,並且將使用該shell 的 PID。它可能與創建文件時使用的值不同。在任何情況下,
$$
inrpm .. > test-$$
和rm test-$$-lock
都會擴展為相同的值。