嗨!今天我們要探討一個在 Linux 中非常重要的主題 – Linux I/O 標準輸入輸出和管線。如果你對 Linux 有一些基本的了解,那麼你肯定聽過這些詞語。本文將帶你深入瞭解它們的意義以及如何在日常使用中受益於它們。
什麼是 Linux I/O?
Linux I/O 是指在 Linux 系統中進行輸入和輸出操作的方法和工具。這些操作可以包括讀取和寫入文件、訪問設備,以及與用戶進行互動。其中,標準輸入和標準輸出是基本的 I/O 流程。
深入理解 Linux I/O
在我們深入探討之前,讓我們先確定我們所談論的是什麼:
- 標準輸入(stdin,代碼為 0):這代表程式運行所需的輸入資料。通常,這些資料來自鍵盤輸入,即我們使用鍵盤向程式提供輸入。
- 標準輸出(stdout,代碼為 1):這代表程式正常運行所產生的輸出資料。當你運行一個命令,這些結果通常會顯示在終端屏幕上,並且被視為標準輸出。
- 標準錯誤輸出(stderr,代碼為 2):這代表當程式出錯時,用於通知使用者的訊息,或者用於呈現程式狀態的訊息。通常,這些錯誤訊息也會顯示在終端上,並被視為標準錯誤輸出。
+-------------------------+ +-------------------------+ +-------------------------+
| 鍵盤(Input) | ---> | 程式(stdin,代碼 0) | ---> | 終端(Output) |
+-------------------------+ +-------------------------+ +-------------------------+
標準輸入 (stdin) 程式的輸入資料 標準輸出 (stdout)
↓
+-------------------------+
| 程式(stderr,代碼 2) |
+-------------------------+
程式的錯誤訊息
標準輸入(stdin,代碼為 0)
標準輸入代表程式運行所需的輸入資料。通常,這些資料來自鍵盤輸入。讓我們看一個例子:
舉例: 假設你有一個名為 my_program
的程式,它需要用戶輸入一個數字,然後進行計算。這個程式可能如下運行:
$ ./my_program
請輸入一個數字:10
計算結果:20
在這個例子中,用戶通過鍵盤輸入了數字 10,作為標準輸入提供給了 my_program
,程式接收到這個輸入並進行計算。
標準輸出(stdout,代碼為 1)
標準輸出代表程式正常運行所產生的輸出資料。當你運行一個命令,這些結果通常會顯示在終端屏幕上。讓我們看一個例子:
舉例: 假設你使用 ls
命令列出目錄中的文件,輸出如下:
$ ls
file1.txt file2.txt file3.txt
在這個例子中,ls
命令的輸出顯示在終端屏幕上,這是標準輸出的典型示例。
標準錯誤輸出(stderr,代碼為 2)
標準錯誤輸出代表當程式出錯時通知使用者的訊息,或者用於呈現程式狀態的訊息。通常,這些錯誤訊息也會顯示在終端上。讓我們看一個例子:
舉例: 假設你嘗試打開一個不存在的文件:
$ cat non_existent_file.txt
cat: non_existent_file.txt: No such file or directory
在這個例子中,cat
命令嘗試打開一個不存在的文件,並生成了錯誤訊息,該訊息顯示在終端上,這是標準錯誤輸出的示例。
以上是對標準輸入、標準輸出和標準錯誤輸出的說明和示例。這些流是 Linux 中重要的 I/O 概念,對於理解和使用命令和程序非常重要。
使用 I/O 重定向
有時候,我們希望將輸入和輸出重定向到文件,這就是 I/O 重定向派上用場的時候。使用 <
來重定向輸入,使用 >
來重定向輸出。例如,要將命令的輸出保存到文件中,你可以使用以下命令:
標準輸入(stdin,代碼為 0)
標準輸入重定向允許將外部文件的內容作為程序的輸入,而不是依賴用戶的鍵盤輸入。這在處理大量數據或自動化任務時非常有用。
舉例: 假設你有一個文件 input.txt
包含以下內容:
這是文件的內容。
它將被用作標準輸入。
現在,你可以使用以下命令將 input.txt
的內容重定向為程序的標準輸入:
$ ./my_program < input.txt
這樣,my_program
將使用 input.txt
中的內容作為其標準輸入。
標準輸出(stdout,代碼為 1)
標準輸出重定向允許將程序的輸出保存到文件中,而不是顯示在終端屏幕上。這對於捕獲命令的輸出或生成日誌非常有用。
舉例: 假設你運行以下命令來列出目錄中的文件:
$ ls file1.txt file2.txt file3.txt
現在,你可以使用以下命令將 ls
命令的輸出保存到文件 output.txt
中:
$ ls > output.txt
這樣,ls
命令的輸出將不再顯示在終端屏幕上,而是保存在 output.txt
文件中。當執行此指令時,如果 output.txt 不存在,系統會自動建立此檔案,並將 ls 指令的輸出寫入其中。但如果 output.txt 已經存在,系統會先清空該檔案的內容,然後再將 ls 的輸出寫入其中。因此,如果 output.txt 檔案中原本存在舊資料,這些資料將會被全部清除。
如果想要以附加的方式把程式的輸出放在原本的檔案內容之後,可以使用 >>
,其用法也是非常類似
$ ls >> output.txt
這樣,他就會在 output.txt
檔案中,於原本的 ls
輸出之後,再加上一行。
標準錯誤輸出(stderr,代碼為 2)
標準錯誤輸出重定向允許將程序的錯誤訊息保存到文件中,而不是混合在標準輸出中。這有助於更好地處理錯誤情況。
舉例: 假設你嘗試打開一個不存在的文件:
$ cat non_existent_file.txt
cat: non_existent_file.txt: No such file or directory
現在,你可以使用以下命令將 cat
命令的錯誤訊息保存到文件 error.log
中:
$ cat non_existent_file.txt 2> error.log
這樣,錯誤訊息將不再顯示在終端屏幕上,而是保存在 error.log
文件中。
2>&1
:這個操作符用於將標準錯誤輸出重定向到標準輸出。這樣可以將錯誤訊息和標準輸出一起顯示在終端上,或將它們一起重定向到文件。
舉例:以下命令將 ls
命令的標準輸出和錯誤輸出都保存到 error.log
文件中
$ cat non_existent_file.txt > error.log 2>&1
以上是有關使用 I/O 重定向的說明和示例,以及它如何影響標準輸入、標準輸出和標準錯誤輸出的操作。
管線操作:將命令串在一起
管線操作(|)是一種強大的技巧,它允許你將多個命令連接在一起,以實現更複雜的操作。例如,你可以使用管線將一個命令的輸出作為另一個命令的輸入。以下是一個簡單的示例:
舉例 1:過濾錯誤訊息
有時你可能只想查看錯誤訊息,而不關心標準輸出。你可以使用管線操作過濾出錯誤訊息,將其顯示在終端上:
$ my_command 2>&1 | grep "error"
在這個例子中,2>&1
將標準錯誤輸出合併到標準輸出,然後使用 grep
命令過濾包含 “error” 的行,並將它們顯示在終端上。
舉例 2:將錯誤訊息記錄到文件
假設你運行一個可能會生成錯誤訊息的命令,你可以使用管線操作將錯誤訊息重定向到一個文件中,同時將標準輸出顯示在終端上:
$ my_command 2> error.log | tee output.log
在這個例子中,2>
將標準錯誤輸出重定向到 error.log
文件,而 tee
命令將標準輸出複製到 output.log
文件,並顯示在終端上。這樣,你可以同時檢查錯誤訊息和標準輸出。
Linux I/O 標準輸入輸出和管線是 Linux 使用中不可或缺的一部分。通過深入理解它們,你可以更有效地使用 Linux,執行各種任務
Linux I/O 特殊檔案的進階用法
/dev/null
- 用途:
/dev/null
被稱為空設備,它接受一切輸入,但將其丟棄。這個檔案通常用於丟棄不需要的輸出或輸入。 - 範例:假設你想要運行一個命令,但不關心其輸出,你可以使用
/dev/null
將其輸出丟棄,在寫 crontab 時特別好用
/path/to/script.sh > /dev/null 2>&1
/dev/zero
- 用途:
/dev/zero
是一個無窮的資源,它產生連續的 NUL 字節(二進制值 0)。這個檔案通常用於創建空白文件或測試寫入操作。 - 範例:假設你想要創建一個 1MB 的空白文件,你可以使用
/dev/zero
:
$ dd if=/dev/zero of=blank_file bs=1M count=1
/dev/random
與 /dev/urandom
- 用途:
/dev/random
和/dev/urandom
提供隨機數生成。/dev/random
提供高品質的隨機數,但可能阻塞。/dev/urandom
則不會阻塞,缺點就是資料沒有那麼隨機 (可能會重複)。 - 範例:這個命令將從
/dev/random
讀取 12 個字節的高品質隨機數據,然後將其轉換為 Base64 格式,生成一個安全密碼。但要注意,這個命令可能會阻塞,直到有足夠的隨機性可用。
$ dd if=/dev/random bs=1 count=12 | base64
/dev/full
- 用途:
/dev/full
代表一個已滿的設備。如果你向它寫入數據,它將永遠不會返回,並且將無限期地阻塞。 - 範例:這個檔案通常用於測試處理設備已滿的情況。例如,以下命令將永遠阻塞,因為
/dev/full
已滿,無法再寫入數據
$ cat large_file > /dev/full
- 中文參考資料:
- 英文參考資料:
延伸閱讀:如何在 Linux 中設定防火牆 ? CentOS firewall-cmd 設定防火牆規則與 firewall zones 教學
延伸閱讀:如何快速在Linux中開機自動化?5分鐘使用教學 /etc/rc.local