stdin、stdout和stderr是在啟動Linux命令時建立的三個資料流。您可以使用它們來判斷您的指令碼是被管道傳輸還是被重定向。我們教你怎麼做。
一旦您開始學習Linux和類Unix作業系統,就會遇到stdin、stdout和stederr這些術語。這是在執行Linux命令時建立的三個標準流。在計算中,流是可以傳輸資料的東西。對於這些流,該資料是文字。
資料流和水流一樣,有兩端。它們有一個來源和一個流出。無論您使用哪個Linux命令,都會提供每個流的一端。另一端由啟動命令的shell決定。根據啟動命令的命令列,該端將連線到終端視窗、連線到管道或重定向到檔案或其他命令。
在Linux中,stdin是標準的輸入流。它接受文字作為輸入。從命令到shell的文字輸出透過stdout(標準輸出)流傳遞。來自命令的錯誤訊息透過stderr(標準錯誤)流傳送。
所以您可以看到有兩個輸出流,stdout和stderr,以及一個輸入流stdin。因為錯誤訊息和正常輸出都有自己的管道將它們傳輸到終端視窗,所以它們可以彼此獨立地處理。
Linux中的流和其他幾乎所有東西一樣,都被當作檔案來對待。可以從檔案中讀取文字,也可以將文字寫入檔案。這兩個動作都涉及一個數據流。因此,將資料流作為檔案進行處理的概念並不是那麼簡單。
與程序關聯的每個檔案都分配了一個唯一的編號來標識它。這稱為檔案描述符。每當需要對檔案執行操作時,都會使用檔案描述符來標識檔案。
這些值始終用於stdin、stdout和stderr:
為了便於某人對某一主題的介紹,一種常見的技巧是教授該主題的簡化版本。例如,關於語法,我們被告知規則是“E之前的I,C之後的除外”。但實際上,這個規則的例外情況比遵守它的情況要多。
同樣,在討論stdin、stdout和stderr時,可以方便地提出一個公認的公理,即程序既不知道也不關心它的三個標準流在哪裡終止。程序是否應該關心其輸出是傳送到終端還是被重定向到檔案中?它甚至能分辨出它的輸入是來自鍵盤還是從另一個程序傳入的嗎?
實際上,一個程序確實知道或者至少它可以發現,如果它選擇檢查,並且如果軟體作者決定新增這個功能,它可以相應地改變它的行為。
我們可以很容易地看到這種行為的變化。請嘗試以下兩個命令:
lsls | cat如果ls命令的輸出(stdout)透過管道傳輸到另一個命令中,則ls命令的行為不同。切換到單列輸出的是ls,而不是cat執行的轉換。如果ls的輸出被重定向,它也會執行相同的操作:
ls > capture.txtcat capture.txt由專用流傳遞錯誤訊息有一個好處。這意味著我們可以將命令的輸出(stdout)重定向到一個檔案,並且仍然可以在終端視窗中看到任何錯誤訊息(stderr)。如果需要,您可以在錯誤發生時對其作出反應。它還阻止錯誤訊息汙染stdout重定向到的檔案。
在編輯器中鍵入以下文字並將其儲存到名為錯誤.sh.
#!/bin/bash echo "About to try to access a file that doesn't exist" cat bad-filename.txt使用以下命令使指令碼可執行:
chmod +x error.sh指令碼的第一行透過stdout流將文本回顯到終端視窗。第二行嘗試訪問不存在的檔案。這將生成透過stderr傳遞的錯誤訊息。
使用以下命令執行指令碼:
./error.sh我們可以看到輸出流stdout和stderr都顯示在終端視窗中。
讓我們嘗試將輸出重定向到一個檔案:
./error.sh > capture.txt透過stderr傳遞的錯誤訊息仍然傳送到終端視窗。我們可以檢查檔案的內容,看看stdout輸出是否進入了該檔案。
cat capture.txtstdin的輸出按預期重定向到檔案。
預設情況下,>;重定向符號與標準輸出一起工作。可以使用其中一個數字檔案描述符來指示要重定向的標準輸出流。
要顯式重定向stdout,請使用以下重定向指令:
1>要顯式重定向stderr,請使用以下重定向指令:
2>讓我們再次嘗試測試,這次我們將使用2>;:
./error.sh 2> capture.txt錯誤訊息被重定向,標準輸出回顯訊息被髮送到終端視窗:
讓我們看看裡面有什麼捕獲.txt檔案。
cat capture.txtstderr訊息在捕獲.txt一如預期。
當然,如果我們可以將stdout或stderr重定向到一個彼此獨立的檔案,我們應該能夠同時將它們重定向到兩個不同的檔案?
是的,我們可以。此命令將stdout指向一個名為捕獲.txt和一個名為錯誤表.
./error.sh 1> capture.txt 2> error.txt因為輸出流–標準輸出和標準錯誤都被重定向到檔案,所以終端視窗中沒有可見的輸出。我們返回到命令列提示符,好像什麼都沒有發生。
讓我們檢查每個檔案的內容:
cat capture.txt cat error.txt這很好,我們將每個標準輸出流都放到了自己的專用檔案中。我們唯一能做的其他組合是將stdout和stderr傳送到同一個檔案。
我們可以透過以下命令來實現這一點:
./error.sh > capture.txt 2>&1我們把它分解一下。
沒有可見的輸出。這是令人鼓舞的。
讓我們檢查一下捕獲.txt歸檔看看裡面有什麼。
cat capture.txtstdout和stderr流都已重定向到單個目標檔案。
要重定向流的輸出並將其靜默地丟棄,請將輸出定向到/dev/null。
我們討論了命令如何檢測是否有任何流被重定向,以及如何選擇相應地改變其行為。我們能用自己的指令碼來完成嗎?是的,我們可以。這是一個很容易理解和運用的技巧。
在編輯器中鍵入以下文字並將其另存為輸入.sh.
#!/bin/bash if [ -t 0 ]; then echo stdin coming from keyboard else echo stdin coming from a pipe or a file fi使用以下命令使其可執行:
chmod +x input.sh聰明的部分是方括號內的測試。如果與檔案描述符關聯的檔案在終端視窗中終止,-t(terminal)選項將返回true(0)。我們使用檔案描述符0作為測試的引數,它表示stdin。
如果stdin連線到終端視窗,測試將被證明是正確的。如果stdin連線到檔案或管道,測試將失敗。
我們可以使用任何方便的文字檔案來生成指令碼的輸入。我們用的是一個叫做虛擬.txt.
./input.sh < dummy.txt輸出顯示指令碼識別出輸入不是來自鍵盤,而是來自檔案。如果您選擇這樣做,您可以相應地改變指令碼的行為。
那是一個檔案重定向,讓我們用管道試試。
cat dummy.txt | ./input.sh指令碼識別出它的輸入正在透過管道傳輸到其中。或者更準確地說,它再次識別stdin流沒有連線到終端視窗。
讓我們既不使用管道也不使用重定向來執行指令碼。
./input.shstdin流連線到終端視窗,指令碼相應地報告這一點。
為了在輸出流中檢查同樣的內容,我們需要一個新的指令碼。在編輯器中鍵入以下內容並將其另存為輸出.sh.
#!/bin/bash if [ -t 1 ]; then echo stdout is going to the terminal window else echo stdout is being redirected or piped fi使用以下命令使其可執行:
chmod +x input.sh這個指令碼唯一重要的變化是方括號中的測試。我們使用數字1來表示stdout的檔案描述符。
讓我們試試看。我們將透過cat傳輸輸出。
./output | cat指令碼識別出它的輸出不會直接傳送到終端視窗。
我們還可以透過將輸出重定向到檔案來測試指令碼。
./output.sh > capture.txt沒有輸出到終端視窗,我們將靜默地返回到命令提示符。如我們所料。
我們可以看看裡面捕獲.txt檢視捕獲的內容。使用以下命令執行此操作。
cat capture.sh同樣,我們指令碼中的簡單測試檢測到stdout流沒有被直接傳送到終端視窗。
如果我們在沒有任何管道或重定向的情況下執行指令碼,它應該會檢測到stdout正被直接傳遞到終端視窗。
./output.sh這正是我們看到的。
知道如何判斷指令碼是否連線到終端視窗、管道或正在重定向,可以相應地調整它們的行為。
日誌記錄和診斷輸出可以更詳細,也可以更詳細,這取決於它是進入螢幕還是進入檔案。錯誤訊息可以記錄到與正常程式輸出不同的檔案中。
通常情況下,更多的知識帶來更多的選擇。
...討論這兩個函式之間的區別。 目錄 1. 概述和主要區別 2. 什麼是getc 3. 什麼是getchar 4. getc和getchar的相似性 5. 並列比較-表格形式的getc與getchar 6. 摘要 什麼是getc公司(getc)? 它是一個函式,用於從輸入流(如檔案或鍵盤)中讀取字...
...面仍然是為internetexplorer設計的,否則googlechrome是你在Linux上的最佳選擇)。它帶有Flash,可以執行Netflix而不需要做任何額外的工作。Chrome也是Firefox擴充套件和附加元件的最佳選擇。 ...
...供的跨平臺框架的一個例子。它最初是作為.NET框架在Linux上的開源實現而設計的。從那時起,它變成了更多的東西,支援多種不同的作業系統。 ...
... 類Unix系統上的所有檔案都有分配給這三個類的許可權,這些許可權決定了這些類可以對給定檔案執行哪些操作。 ...
...johnnyfive文件中提供的一段示例程式碼,它允許使用鍵盤上的箭頭鍵控制伺服。完整的程式碼可在約翰尼-五.io,但我們將在這裡詳細介紹,以充分了解它的工作原理。 ...
... 另一方面,macOS上的遊戲體驗在過去幾年中基本保持不變。儘管遊戲平臺仍然支援macOS,但遊戲似乎並不是蘋果的首要任務。讓我們仔細看看它的特點。 ...
...這是標記,表示標記中的標題。數字符號(#)必須是行上的第一個字元,後跟空格。 name部分包含一個快捷的單行,其中包括命令的名稱、空格、連字元(-)、空格,然後是命令所做的非常簡短的描述。 簡介 概要包含命令列可...
...所以在大多數情況下,您不會收到電子郵件。 相關:Linux上的stdin、stdout和stderr是什麼? 現在,是時候在中鍵入命令了。對於本例,我們將使用一個名為掃描.sh刪除*.bak、*.tmp和*.o檔案。鍵入命令的路徑,如下所示,然後按Enter鍵...
... 交換是一種將隨機存取儲存器(RAM)中的資料寫入硬碟上的特殊位置(交換分割槽或交換檔案)以釋放RAM的技術。 Linux有一個稱為交換值的設定。關於這個設定控制什麼,有很多困惑。對交換性最常見的錯誤描述是,它為RAM使...
...我們日期戳和時間戳都新增到了日誌檔案中。 相關:Linux上的stdin、stdout和stderr是什麼? 那是echo的劇目 一個簡單的命令,但不可或缺。如果它不存在,我們就得發明它。 畢竟,宙斯的惡作劇有一些好處。