Linux 上的標準輸入、標準輸出和標準錯誤是什麼?

已發表: 2022-01-29
Linux 計算機上的終端窗口
Fatmawati Achmad Zaenuri/Shutterstock.com

stdinstdoutstderr是啟動 Linux 命令時創建的三個數據流。 您可以使用它們來判斷您的腳本是否正在通過管道傳輸或重定向。 我們向您展示如何。

流連接兩個點

一旦您開始了解 Linux 和類 Unix 操作系統,您就會遇到術語stdinstdoutstederr 。 這是執行 Linux 命令時建立的三個標準流。 在計算中,流是可以傳輸數據的東西。 在這些流的情況下,該數據是文本。

數據流,就像水流一樣,有兩端。 他們有一個來源和一個流出。 無論您使用哪個 Linux 命令,都可以提供每個流的一端。 另一端由啟動命令的 shell 決定。 根據啟動命令的命令行,該端將連接到終端窗口、連接到管道或重定向到文件或其他命令。

Linux 標準流

在 Linux 中, stdin是標準輸入流。 這接受文本作為其輸入。 從命令到 shell 的文本輸出通過stdout (標準輸出)流傳遞。 命令中的錯誤消息通過stderr (標準錯誤)流發送。

因此,您可以看到有兩個輸出流stdoutstderr以及一個輸入流stdin 。 因為錯誤消息和正常輸出都有自己的管道將它們傳送到終端窗口,所以它們可以相互獨立地處理。

流像文件一樣被處理

Linux 中的流——就像幾乎所有其他東西一樣——被視為文件。 您可以從文件中讀取文本,也可以將文本寫入文件。 這兩個動作都涉及數據流。 因此,將數據流作為文件處理的概念並沒有那麼牽強。

廣告

與進程關聯的每個文件都分配有一個唯一編號來標識它。 這稱為文件描述符。 每當需要對文件執行操作時,都會使用文件描述符來標識文件。

這些值始終用於stdinstdout,stderr

  • 0 :標準輸入
  • 1 :標準輸出
  • 2 :標準錯誤

對管道和重定向做出反應

為了簡化某人對某個主題的介紹,一種常見的技術是教授該主題的簡化版本。 例如,對於語法,我們被告知規則是“I 在 E 之前,C 之後除外”。 但實際上,這條規則的例外情況比遵守它的情況要多。

類似地,在談論stdinstdoutstderr時,可以方便地提出一個公認的公理,即一個進程既不知道也不關心它的三個標準流在哪裡終止。 進程是否應該關心它的輸出是發送到終端還是被重定向到文件中? 它甚至可以判斷它的輸入是來自鍵盤還是從另一個進程通過管道輸入?

實際上,一個進程確實知道——或者至少它可以發現,如果它選擇檢查的話——並且如果軟件作者決定添加該功能,它可以相應地改變它的行為。

廣告

我們可以很容易地看到這種行為變化。 試試這兩個命令:

 ls 

 ls | 貓

如果ls命令的輸出 ( stdout ) 被傳送到另一個命令中,則 ls 命令的行為會有所不同。 是ls切換到單列輸出,而不是cat執行的轉換。 如果它的輸出被重定向, ls也會做同樣的事情:

 ls > 捕獲.txt 

 貓捕獲.txt 

重定向標準輸出和標準錯誤

通過專用流傳遞錯誤消息是有好處的。 這意味著我們可以將命令的輸出( stdout )重定向到文件,並且仍然在終端窗口中看到任何錯誤消息( stderr )。 如果需要,您可以在錯誤發生時對錯誤做出反應。 它還阻止錯誤消息污染stdout已重定向到的文件。

在編輯器中鍵入以下文本並將其保存到名為 error.sh 的文件中。

 #!/bin/bash

echo "即將嘗試訪問不存在的文件"
貓壞文件名.txt

使用以下命令使腳本可執行:

 chmod +x 錯誤.sh

腳本的第一行通過stdout流將文本回顯到終端窗口。 第二行嘗試訪問一個不存在的文件。 這將生成通過stderr傳遞的錯誤消息。

使用以下命令運行腳本:

 ./error.sh 

我們可以看到,兩個輸出流stdoutstderr都已顯示在終端窗口中。

讓我們嘗試將輸出重定向到一個文件:

 ./error.sh > 捕獲.txt 

廣告

通過stderr傳遞的錯誤消息仍然發送到終端窗口。 我們可以檢查文件的內容,看看stdout輸出是否到了文件中。

 貓捕獲.txt 

stdin的輸出按預期重定向到文件。

>重定向符號默認與stdout一起使用。 您可以使用數字文件描述符之一來指示您希望重定向的標準輸出流。

要顯式重定向stdout ,請使用此重定向指令:

 1>

要顯式重定向stderr ,請使用以下重定向指令:

 2>

讓我們再次嘗試測試,這次我們將使用2>

 ./error.sh 2> 捕獲.txt 

錯誤消息被重定向, stdout echo顯消息被發送到終端窗口:

讓我們看看 capture.txt 文件中有什麼。

 貓捕獲.txt 

stderr消息按預期在 capture.txt 中。

重定向標準輸出和標準錯誤

當然,如果我們可以將stdoutstderr重定向到彼此獨立的文件,我們應該能夠同時將它們重定向到兩個不同的文件?

廣告

我們可以。 該命令將stdout指向一個名為 capture.txt 的文件,並將stderr指向一個名為 error.txt 的文件。

 ./error.sh 1> 捕獲.txt 2> 錯誤.txt 

因為輸出流——標準輸出和標準錯誤——都被重定向到文件,所以終端窗口中沒有可見的輸出。 我們返回到命令行提示符,就好像什麼都沒發生一樣。

讓我們檢查每個文件的內容:

 貓捕獲.txt
 貓錯誤.txt 

將 stdout 和 stderr 重定向到同一個文件

這很好,我們已經將每個標準輸出流放到了它自己的專用文件中。 我們可以做的唯一其他組合是將stdoutstderr發送到同一個文件。

我們可以使用以下命令來實現:

 ./error.sh > capture.txt 2>&1

讓我們分解一下。

  • ./error.sh :啟動 error.sh 腳本文件。
  • > capture.txt :將stdout流重定向到 capture.txt 文件。 >1>的簡寫。
  • 2>&1 :這使用 &> 重定向指令。 該指令允許您告訴 shell 使一個流到達與另一個流相同的目的地。 在這種情況下,我們說“將流 2, stderr重定向到流 1, stdout被重定向到的同一目的地。”

沒有可見的輸出。 這是令人鼓舞的。

讓我們檢查一下 capture.txt 文件,看看裡面有什麼。

 貓捕獲.txt 

stdoutstderr流都已重定向到單個目標文件。

要將流的輸出重定向並靜默丟棄,請將輸出定向到/dev/null

檢測腳本中的重定向

我們討論了命令如何檢測是否有任何流被重定向,並可以選擇相應地改變其行為。 我們可以在自己的腳本中實現這一點嗎? 我們可以。 這是一種非常容易理解和使用的技術。

廣告

在編輯器中鍵入以下文本並將其保存為 input.sh。

 #!/bin/bash

如果 [ -t 0 ]; 然後

  來自鍵盤的 echo stdin
 
別的

  來自管道或文件的 echo 標準輸入
 
菲

使用以下命令使其可執行:

 chmod +x 輸入.sh

聰明的部分是方括號內的測試。 如果與文件描述符關聯的文件在終端窗口中終止,則-t (終端)選項返回 true (0)。 我們使用文件描述符 0 作為測試的參數,它代表stdin

如果stdin連接到終端窗口,則測試將證明是正確的。 如果stdin連接到文件或管道,則測試將失敗。

我們可以使用任何方便的文本文件來生成腳本的輸入。 在這裡,我們使用了一個名為 dummy.txt 的文件。

 ./input.sh < 虛擬.txt 

輸出顯示腳本識別出輸入不是來自鍵盤,而是來自文件。 如果您選擇這樣做,您可以相應地改變腳本的行為。

廣告

那是文件重定向,讓我們用管道試試。

 貓假人.txt | ./input.sh 

該腳本識別出它的輸入正在通過管道傳遞給它。 或者更準確地說,它再次識別出stdin流沒有連接到終端窗口。

讓我們在既不使用管道也不使用重定向的情況下運行腳本。

 ./input.sh 

stdin流連接到終端窗口,腳本會相應地報告這一點。

要檢查輸出流是否相同,我們需要一個新腳本。 在編輯器中輸入以下內容並將其保存為 output.sh。

 #!/bin/bash

如果 [ -t 1 ]; 然後

echo stdout 將進入終端窗口
 
別的

echo stdout 正在被重定向或通過管道傳輸
 
菲

使用以下命令使其可執行:

 chmod +x 輸入.sh

此腳本的唯一重大更改是方括號中的測試。 我們使用數字 1 來表示stdout的文件描述符。

讓我們試試看。 我們將通過cat管道輸出。

 ./輸出 | 貓

廣告

該腳本識別出它的輸出不會直接進入終端窗口。

我們還可以通過將輸出重定向到文件來測試腳本。

 ./output.sh > 捕獲.txt 

終端窗口沒有輸出,我們默默地返回到命令提示符。 正如我們所料。

我們可以查看 capture.txt 文件以查看捕獲的內容。 使用以下命令執行此操作。

 貓捕獲.sh 

同樣,我們腳本中的簡單測試檢測到stdout流沒有直接發送到終端窗口。

廣告

如果我們在沒有任何管道或重定向的情況下運行腳本,它應該檢測到stdout正在直接傳遞到終端窗口。

 ./output.sh 

這正是我們所看到的。

意識流

知道如何判斷您的腳本是連接到終端窗口、管道還是被重定向,您可以相應地調整它們的行為。

日誌和診斷輸出可能或多或少詳細,具體取決於它是進入屏幕還是進入文件。 錯誤消息可以記錄到與正常程序輸出不同的文件中。

通常情況下,更多的知識會帶來更多的選擇。

相關:適合開發人員和愛好者的最佳 Linux 筆記本電腦