我們可以在 Linux 中引用檔案的**輸出**有 4 種類型,這是真的嗎?

我們可以在 Linux 中引用檔案的**輸出**有 4 種類型,這是真的嗎?

是否可以得出 4 種類型的結論?流輸出如果我們不希望它們在執行命令後出現在 CLI 中,我們可以引用 Linux 中的檔案嗎?

對文件的可能引用:

  1. 所有流輸出
  2. 僅標準誤差
  3. 僅標準輸出(包括標準輸出的最終結果)。
  4. stdout 和 stderr(不包括 stdout 的最終結果)。

筆記:

數字 4 的一個例子可能是find / -type f -name php.ini 2>/dev/null。據我了解,使用這個指令我們沒有得到標準誤差,也沒有標準輸出(除了標準輸出的最終結果在本例中,這是我們搜尋的文件(如果找到)。

答案1

有兩個輸出流連接到 Unix 系統上的每個進程:標準輸出(標準輸出,檔案描述符 1)和標準誤(stderr,檔案描述符 2)。這些可以彼此獨立地重定向。標準輸入使用檔案描述符 0。

  • 若要將標準輸出重定向到文件file,請使用>file或更明確的1>file。替換file/dev/null丟棄資料。
  • 若要將標準錯誤重定向到文件file,請使用2>file.
  • 若要將標準誤差重定向到標準輸出所在的位置,請使用2>&1.
  • 若要將標準輸出重定向到標準錯誤所在的位置,請使用1>&2.

不存在流或過程的“最終結果”概念。我想發送到標準輸出的任何內容都可以被視為進程的“結果”,除非它也將數據輸出到它自己打開的某個文件或具有其他副作用(例如從目錄中取消文件鏈接,在這種情況下)的rm,或在 ) 的情況下處理多個網路連線sshd。進程也返回退出狀態(零表示“成功”,非零表示“失敗”),可以將其視為該進程的“結果”,但這不一定與進程的輸出流相關。

流也可以重定向到附加模式,這意味著如果重定向到文件,則該文件最初不會被截斷,並且流上的任何資料都會附加到文件末尾。透過使用>>file而不是來做到這一點>file

在問題的註釋中,命令

find / -type f -name php.ini 2>/dev/null

給出。這會重定向(丟棄)僅有的標準誤差。標準輸出流根本不重定向,因此在控制台或終端中完整可見。如果它是管道的中間部分,則標準輸出流將輸入到管道中下一個命令的標準輸入中。

總而言之,我想說有(不是四個)輸出流。這些可以以各種方式獨立地重新導向,其中包括丟棄它們的內容。

答案2

每一個流程按照慣例,可以使用三個標準檔案描述符。這些檔案描述符可作為流使用:stdinstdoutstderr

預設情況下,當您從 shell (CLI) 啟動進程時,第一個進程連接到終端(或終端模擬器,如 xterm)的輸入,另外兩個連接到終端的輸出。

您可以指示 shell 將它們重新導向到其他地方,例如/dev/null(它們被吞噬的地方)。您可以獨立為stdout和執行此操作stderr。那麼對於這種情況,確實有四種可能:

command 
command > /dev/null
command 2> /dev/null
command > /dev/null 2> /dev/null

但沒有什麼可以阻止您將其中一個或兩個重定向到其他地方:

command > /tmp/myout 2> /tmp/myerr

在這種情況下,您的終端也不會得到任何輸出,但您可以稍後在檔案/tmp/myout和中讀取它/tmp/myerr

答案3

情況比你的問題所暗示的更簡單,也更複雜。來解釋一下什麼善行難陀說在他的回答,有兩個按慣例配置並用於輸出的標準(常規)I/O 流(文件描述符):stdout(文件描述符 1)和 stderr(文件描述符 2)。我們的規範問題, shell 的控制和重定向運算子是什麼?,討論如何重定向它們。天真地,我們可以列舉五種不同的組合:

╔══════════════════════════════╦═════════════════════════════════════════════╗
║                              ║                   stderr                    ║
║                              ╟─────────────────────┬───────────────────────╢
║                              ║       default       │                       ║
║                              ║ (same as the shell) │       redirected      ║
╠════════╤═════════════════════╬═════════════════════╦═══════════════════════╣
║        │       default       ║                     ║                       ║
║        │ (same as the shell) ║          1          ║           2           ║
║        ├─────────────────────╠═════════════════════╬═══════════════════════╣
║ stdout │                     ║                     ║ 4. redirected         ║
║        │                     ║                     ║    to the same file   ║
║        │      redirected     ║          3          ╟───────────────────────╢
║        │                     ║                     ║ 5. redirected         ║
║        │                     ║                     ║    to different files ║
╚════════╧═════════════════════╩═════════════════════╩═══════════════════════╝

但如果你算是/dev/null與文件不同,追加模式作為一種特殊情況,讀寫模式與只寫模式不同,管道與文件不同,那麼組合的數量就會呈指數級增長。然而,正如反覆指出的,「stdout 的最終結果」不是標準的 Unix/Linux/bash 短語。

只有兩個?

其他答案(也許是明智的)將自己限制為 stdout 和 stderr (文件描述符 1 和 2)。我(魯莽地?)相信這個問題的完整答案應該解決其他文件描述符可用的事實 - 多達數百,數千,甚至超過一百萬。例如,如果執行類似 的命令diff file1 file2diff程式將開啟file1file2,核心可能會分配檔案描述符 3 和 4。以下位置討論了重定向大於 2 的檔案描述符:

例如,請參閱以下高檔案描述符範例:

$ 貓犬.c
#include <stdio.h>
#include <字串.h>

主要的()
{
        int i,len;
        char msg[] = "你好,狗。\n";

        len = strlen(msg);
        我=寫(17,味精,長度);
        如果 (i == len)
                printf("成功!i = %d = len\n", i);
        否則如果 (i == -1)
            {
                printf("錯誤!i = %d (len = %d)\n", i, len);
                錯誤(“”);
            }
        別的
                printf("意外結果:i = %d, len = %d\n", i, len);
}

$ 製作犬類
cc 犬.c -o 犬

$ ./犬類
錯誤!我 = -1 (len = 12)
錯誤的文件描述符

$ ./canine 17> 動物
成功!我 = 12 = 長度

$ ls -l
總計 70
-rw-r--r-- 1我的用戶名 我的群組名    2012年4月12日 13:36 動物
-rwxr-xr-x 1我的用戶名 我的群組名67067 4 月 12 日 13:36 犬
-rw-r--r-- 1我的用戶名 我的群組名   358 四月 12 日 13:36 犬.c

$ 貓 動物
你好,狗。

警告:我不確定上述內容是否適用於所有 shell 的所有版本。

標準程式不會寫入大於 2 的檔案描述符(除非它們透過開啟檔案、建立網路連線或類似方式從核心取得該檔案描述符)。但是,如果您有一個(非標準)程序可以執行此操作,則可以重新導向這些檔案描述符。

而且,如果您只有 100 個檔案描述符,並且只考慮每個檔案描述符是否被重新導向,那麼您就有超過十億 (1,000,000,000,000,000,000,000,000,000,000) 種可能的組合。

相關內容