Linux Programming I/O Redirection、Pipeline   2019-08-26


輸入、輸出、重新導向

標準輸入(STDIN):代碼表示0,程式執行時所需要的輸入資料。
標準輸出(STDOUT):代碼表示1,程式”正常“執行時所產生的輸出資料。
標準錯誤輸出(STDERR):代碼表示2,程式”錯誤“執行時輸出的訊息。
重新導向:改變資料的輸出入方向。


Image source:Piping and Redirection,output,Reading from STDIN in script(Linux)

標準輸出 STDOUT

一般的程式執行結果會顯示在螢幕上,也就是說預設的標準輸出是螢幕。我們可以使用 > 來將標準輸出導向至檔案。
語法:

1
N > FILE
1
Example:將 ```ls -al``` 輸出內容導向至ls.txt

ls -al > ls.txt

1
2
3
4
若當前資料夾中``` ls.txt ```檔案不存在,則為自動生成一個並寫入。
若此檔案存在,則會清除原始內容並寫入```ls -al```輸出資料。
若想要保留原始資料並將輸出內容接續檔案原內容,則可以使用```>>```替換原本的```>```。
Example:

ls -al >> ls.txt

1
2
3
4

## 標準錯誤輸出 STDERR
程式發生錯誤時,錯誤訊息預設也是輸出在螢幕上。
Example:

ls no_file.txt
ls: cannot access no_file.txt: No such file or directory

1
若想要將錯誤訊息輸出至```ls.txt```內,如果下這行command:

ls no_file.txt > ls.txt
ls: cannot access no_file.txt: No such file or directory

1
錯誤訊息依然顯示在螢幕,而```ls.txt```也不會寫入錯誤訊息。原因是```>```預設代碼為```1```,此時我們要指定代碼為```2```,也就是指定將輸出錯誤訊息寫入```ls.txt```內。

ls no_file.txt 2> ls.txt
cat ls.txt
ls: cannot access no_file.txt: No such file or directory

1
若想將標準輸出與標準錯誤輸出的資料一起寫入同個檔案可以這樣寫:

ls no_file.txt > ls.txt 2>&1

1
2
3
```2>&1```代表將**標準錯誤輸出**的資料導入**標準輸出**
不要忘記```>```預設為**正常輸出**。
驗證:

ls no_file.txt > ls.txt 2>&1
cat ls.txt
ls: cannot access no_file.txt: No such file or directory
touch no_file.txt
ls no_file.txt > ls.txt 2>&1
cat ls.txt
no_file.txt

1
2
3
4
原先無```no_file.txt```此檔案,執行```ls```並將錯誤訊息寫入```ls.txt```,新增```no_file.txt```並再一次執行```ls```,可以看到輸出訊息有所變化且正常輸出與錯誤輸出資料都寫入```ls.txt```內。

導向語法有許多組合,以下都可以達到將正常輸出與錯誤輸出寫入同一個檔案內。
Example:

ls no_file.txt 2> ls.txt 1>&2
ls no_file.txt >& ls.txt
ls no_file.txt &> ls.txt

1
2
```>&``` ```&>```為將所有輸出導向至檔案。
實用例子:儲存iptables規則至檔案

iptables-save > iptables.rule

1
2
3
4

## 標準輸入
需要輸入資料的Linux程式若執行時沒有給予資料的話,預設將會從鍵盤讀取資料
Example:

cat
1
1
2
2

1
2
使用```<```,將指定的檔案設定為程式的標準輸入
Example:

cat < ls.txt
no_file.txt

1
2
3
4
5
6
7

## 管線 pipe
若要把兩個或以上的程式輸入出串連起來,可以使用```|```(pipe)。
![](https://i.imgur.com/sN2gQjM.png)
[Image Soruce:鳥哥的 Linux 私房菜 第十章、認識與學習BASH](http://linux.vbird.org/linux_basic/0320bash.php)

Example:

ls | nl

1 file1
2 file2
3 directory3

```

nl為顯示行數的指令。
也就是 ls的輸出透過pipe成為了nl的輸入,達到了可顯示行數的ls功能。

/dev/null

-
一個類似垃圾桶的東西,若將輸出指向至此,則所有輸出將會被捨棄掉。

Reference

GTW-Linux I/O 輸入與輸出重新導向,基礎概念教學

目錄

  1. 輸入、輸出、重新導向
  2. 標準輸出 STDOUT
  3. /dev/null
  4. Reference