iT邦幫忙

2025 iThome 鐵人賽

DAY 19
1

嗨!歡迎回到上班族的命令列生存手冊。還記得最前面幾章介紹的 Standard Input 和 Standard Output 嗎?本章還會用到這個觀念,首先來看 cat 這個指令,現在我們知道 cat 從 Standard Input (也就是你的鍵盤輸入)接收 input,然後印到畫面上。

image-001.gif

現在來印一個文字檔案,像這個 original.txt

$ cat original.txt

現在我們知道 original.txt 作為 standard input 被塞到 cat 裡頭了。這邊其實是 cat 幫你下了這個指令:

$ cat 0< original.txt

再複習,0 的意思是 Standard Input。有兩種輸出,1 則是 Standard Output,2 是 Standard Error。在 POSIX 系統之中,東西都是檔案,被掛在檔案系統之中,Standard Input、Output 和 Error 也都是檔案!(我知道,很酷)。

它們住在哪裡呢?他們住在 dev 目錄下面,你可以這樣查看他們的存在:

https://ithelp.ithome.com.tw/upload/images/20251003/20141615CQQ2EsQfvA.png

$ ls /dev | grep std

回到 cat 的例子,它還需要幫忙把結果輸出到畫面上,也就是 Standard output,完整的指令是這樣:

$ cat 0< original.txt 1> dev/stdout

也就是 original.txt 作為 standard input (編號 0),將 Standard output (編號 1) 輸出到 dev/stdout 就是畫面上。
cat 都幫我們處理好了,不用打這麼多字。(黑貓、白貓、會印字的都是⋯)

還記得在講到 cat 那一章有提到 cat 本意是 Concatenate (連接) 的縮寫,然後教大家怎麼把一個合法來源的小說拼回去嗎?
那個範例是有一個小說檔案被切割成 xaa.txtxab.txtxac.txtxad.txt,然後這樣子拼回去:

$ cat xaa.txt xab.txt xac.txt xad.txt > output.txt

看到那個我們當初說先「略過」的箭頭了嗎?本來 output 是去 Standard Output,用 > 就可以調整他輸出的方式!

兩種箭頭

Override: >

前面在說明不要隨便執行網路上找到的安裝 Script,以 zsh 的 Framework zsh for human 的安裝 Script 為範例,可以用上面學到的方式把它下載成一個檔案,還記得 curl 會把資料都印到畫面上嗎?只需要把他轉移到一個新檔案裡頭即可(而且要不要打副檔名隨意)。

curl -fsSL https://raw.githubusercontent.com/romkatv/zsh4humans/v5/install > install.sh

$ ls 就會看到多出一個 install.sh 檔案,可以試著 cat 他來看看內容。

echo 指令可以把 input 輸出到畫面上,讀者可以試試隨意 echo 一行字,例如這樣:

$ echo 你好! 你好!

這個時候,再 echo 一次,只是這次我們把輸出轉移到剛剛建立好的 install.sh

$ echo "好事會發生" > install.sh

再查看 install.sh 內容,發現內容完全不見了!只留下「好事會發生」!沒錯,如果用一個 > 會直接 Override(覆蓋)目標這點要特別注意!

Append: >>

那有辦法不要覆蓋嗎?可以!只要多打一個 > 就行了,也就是 >>,這樣輸出就會被 Append 放置到最新的一行。一樣用上面已經被覆蓋過的 install.sh 來試試吧。

$ echo "壞事不發生" >> install.sh

https://ithelp.ithome.com.tw/upload/images/20251003/20141615ucw7D7cLqW.png

再來看看目標檔案,是不是多了一行「壞事不發生」?而不是完全取代。

tee 指令

不過,只是改變水流流向無聲無息,能不能順便也輸出一份到畫面上阿?這就要介紹 tee 這個指令了。他可以輸出到檔案時,也同時印東西到畫面上。

這需要配合 Pipe 的使用,有沒有覺得之前學的東西全部一次出現了呢?

$ echo "好事會發生" | tee install.sh

會注意到畫面也印出了「好事會發生」,檢查一下 install.sh 也變成了「好事會發生」。看來 tee 指令預設就是 Override。
那怎麼不覆蓋呢?筆者偷偷去查了一下 tldr 指令,發現可以這樣做:

$ echo "壞事不發生" | tee --append install.sh

或者是直接簡寫成 -a 就行啦,是不是就沒有整個覆蓋了呢?

接下來的章節,一起和筆者一起來看看什麼是 Shell Script,讀者會不會想要自己寫一個呢?讓我們下一章節再見囉。


上一篇
Day18 進階觀念篇:你的 Shell 怎麼這麼棒?fish
下一篇
Day20 進階觀念篇:一個簡單的 Shell Script 和權限
系列文
上班族的命令列 (CLI) 生存手冊25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
chiaominchang222
iT邦新手 5 級 ‧ 2025-10-03 21:18:55

下班來看鐵人文章 又看到回到上班 嚇壞了XD

必須的吧

我要留言

立即登入留言