[Linux] cat

[Linux] cat

很常看別人在 Linux 上使用 <<EOF 這種寫法,不過自己一直沒有去弄懂過…

今天終於決定好好的來查一下,順便應用在要寫的一個 script 裡面~

 

我想要做的是將多行文字寫到一個檔案裡面去~

用 <<EOF (專業術語叫 Here document) 的寫法是:

cat <<EOF > /etc/yum.repos.d/CentOS-Debuginfo.repo
[base-debuginfo]
name=CentOS-7 - Debuginfo
baseurl=http://debuginfo.centos.org/7/$basearch/
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-7
enabled=1
EOF

 

這邊的重點就是 << 代表的是接下來的是一個 delimiter (本例中的 EOF),

在遇到下一個同樣的 delimiter (必須單獨一行) 前,所有的內容都會丟給左邊程式的 stdin~

因此上面的語法意圖是將 [base-debuginfo] 和接下來的那幾行 (不含 EOF),

丟給 cat 的 stdin,然後 cat 會直接將 stdin 的內容輸出到 stdout,

因此用 > 轉向將內容寫到 CentOS-Debuginfo.repo~

 

但是當你用上面的寫法時,會發現寫出來的檔案裡,

$basearch 這個文字不見了,被替換成一個空字串:

[base-debuginfo]
name=CentOS-7 - Debuginfo
baseurl=http://debuginfo.centos.org/7//
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-7
enabled=1

 

這是因為 Here document 的字串裡,會跟 Linux shell 裡用雙引號 “” 括起來的字串一樣,

裡面如果有變數,就會被取代成變數的內容,

而因為平常沒有 $basearch 這個變數,因此內容就為空了~

 

要解決這個問題,將 delimiter 用雙引號 “” 或是單引號 ” 括起來就行了,

不過要記得只要括 << 右邊的 delimiter,結尾的那個是不用的,例如: 

cat <<"EOF" > /etc/yum.repos.d/CentOS-Debuginfo.repo
[base-debuginfo]
name=CentOS-7 - Debuginfo
baseurl=http://debuginfo.centos.org/7/$basearch/
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-7
enabled=1
EOF

 

這樣寫出來的檔案就會是正常的囉,$basearch 的字串完整保留在檔案裡:

[base-debuginfo]
name=CentOS-7 - Debuginfo
baseurl=http://debuginfo.centos.org/7/$basearch/
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-7
enabled=1

  

參考資料:

how does ` cat << EOF` work in bash?

Wikipedia: Here document

 

(本頁面已被瀏覽過 3,218 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料