iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
0
自我挑戰組

30 天不間斷-資工隨筆大雜燴系列 第 27

[Day 27] 自己的 Shell Script 自己寫 - 資料重導向

前言

I/O分別表示(輸入Input/輸出Output),只要透過一行指令就能夠控制你資料的何去何從,應該存在檔案呢,還是顯示在螢幕上呢,又或者是交給其他程式先處理一下?

這些都能夠讓腳本變得更精簡,不用寫一大堆的判斷式來讀檔存檔,幾乎每個腳本都會出現類似的訊息,算是非常重要的概念。

程式導向一般檔案

檔案 FD
標準輸入(standard input) 0
標準輸出(standard output) 1
標準錯誤輸出(standard error output) 2

FD的全名是 file descripter ,FD 的值一定是非負整數,用來描述檔案的型態。

上面三種標準都有預設的輸入或是輸出設備,並且都有相應的 FD,如果要更改設備可以透過 FD 加上運算子來決定資料的走向。

而輸出的部分會藉由 FD 來判斷資料應該導向標準輸出(1)還是標準錯誤輸出(2)。

標準輸入

  • 預設從鍵盤輸入
  • 運算子:<,<<

input.txt 輸入讀進 cat,然後cat再把資料顯示在螢幕上面。

cat < input.txt 

新建一個檔案並命名爲 input.txt

cat << EOF > input.txt 

逐列輸入文字到檔案,當到 input.txt 檔案結尾的時候輸入 EOF 代表 End of File。

heredoc> 第一列
heredoc> 第二列
heredoc> 第三列
heredoc> EOF

標準輸出

  • 預設輸出到螢幕
  • 運算子: >,>>

如果不加任何運算子,ls 的結果預設輸出到螢幕

ls

如果想要改爲輸出到檔案,可以使用>>>

ls>output.txt #如果有舊資料,先清空再存入新資料
ls 1> output.xtx #通常標準輸出的 FD 會省略,如上面的例子

ls 指令的結果儲存在 output.txt中,如果 input.txt 檔案不存在,則執行期間新建一個。

ls>>output.txt  #把新資料附加在原資料後面

標準錯誤輸出

  • 預設輸出到螢幕
  • 運算子 >,>>
  • 實際使用:2>,2>>
cat null_file > output.txt

此時螢幕會顯示

rm: cannot remove 'output.txt': No such file or directory

而 output.txt 是空的。

原因是上面期望把訊息標準輸出到檔案,但是此時產生了錯誤訊息,因此應該加上相應的 FD (2),最後導向到標準錯誤輸出。

cat null_file 2> output.txt

此時 output.txt 會顯示

rm: cannot remove 'output.txt': No such file or directory

簡單來說這一行是把標準輸出還有標準錯誤輸出的資料全部導到 output.txt。

原理是代表先把標準錯誤輸出導到標準輸出,此時標準輸出除了原本自己的資料也包含了錯誤輸出,因此最後靠着>就可以把所有的資料導向 output.txt

cat null_file 2>&1 output.txt

當然如果反着寫把 2>&1 改成1>&2 就只是先把標準輸入先導到錯誤輸出,最後全部的資料由標準錯誤輸出匯入。

另外還有兩種寫法效果也是一樣

cat null_file &> output.txt
cat null_file>& output.txt

有一個特別的檔案 dev/null 當做系統的空裝置,只要寫入這個檔案就會立刻被丟掉,今天我們要尋找家目錄底下的 .bashrc 檔,如果有遇到錯誤訊息(例如 permission denied)就導向 /dev/null,把錯誤訊息丟掉,只剩下有確實找到的檔案顯示在螢幕上。

find /home -name .bashrc 2>/dev/null

雙重資料流導向 

ls 的輸出結果顯示在螢幕且存在 output.txt 裏面

ls | tee output.txt #覆蓋原檔案
ls | tee -a output.txt #附加在原檔案之後

程式導向程式-管線

現在 /home 底下有兩個資料夾 aming,logt+found

我們利用下面的指令把 ls /home的結果透過管線(|)導到 nl,把每一列都加上行號,別忘了ls|nl 會產生最後的輸出,最後預設輸出到螢幕。

ls /home |nl
1	aming
2   lost+found

參考資料

https://www.guru99.com/linux-redirection.html#3
https://blog.gtwang.org/linux/linux-io-input-output-redirection-operators/
http://linux.vbird.org/linux_basic/0320bash.php#redirect


上一篇
[Day 26] 自己的 Shell Script 自己寫 - 函式篇
下一篇
[Day 28] Pipenv 套件管理工具
系列文
30 天不間斷-資工隨筆大雜燴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言