檔案描述符2打開用於讀寫

檔案描述符2打開用於讀寫

這是我從我寫的 stderr 讀取的 C 程序

#include <uninstd.h>
#include <stdio.h>

int main(void) {
 char buff[3];
 read(2, buff, sizeof(buff));
 printf("%s", buff");
 return 0;
}

我的問題是如何向它發送 stderr。大多數搜尋顯示為 bash 重定向

command 2> file

但這會將 stderr 發送到檔案。

我怎樣才能傳遞到我的程式。就像點一樣,

command 2 "somthing here" ./myprogram

感謝您的回答。

答案1

鑑於大多數參考書和文件總是將標準錯誤作為輸出,這讓許多人感到驚訝,事實上它通常是已經打開讀取+寫。非常喜歡你的節目從檔案描述符 2 讀取。

(注意:在這個答案中,我使用實際的文件描述符編號。C流例如stderr不需要實際對應這些檔案描述符,因為程式可以更改它們,並且它增加了談論 C 流的作用的一層混亂。您的程式正在使用read()

檔案描述符2打開用於讀寫

對於在父行程中未使用重定向的登入工作階段中的程序,檔案描述符 2(標準錯誤)通常是檔案描述符 0(標準輸入)的副本。它們都引用相同的底層文件描述,它通常是登入會話的終端(由ttymon或在舊系統上getty在會話開始時開啟和複製)。

如果從檔案描述符 2 讀取,您將獲得與從檔案描述符 0 讀取相同的輸入。

順便說一句:從文件描述符 2 讀取資料經常用於密碼輸入等操作;在該/dev/tty裝置被引入之前,大約在 1977 年。

儘管/dev/ttyPOSIX 已經存在很長時間了,超過 40 年了,但它仍然要求檔案描述符 2 也打開以供讀取。

你的程式沒有做什麼

從檔案描述符 2 讀取另一個程式的輸出是另一回事。你不能輕易做到這一點透過它自己,不將標準輸出與標準誤差合併。它通常涉及一系列3>&1 1>&2 2>&3或類似的交換。一些 shell 透過呼叫允許在輸出檔案描述符 2 上使用管道

prog1 2| prog2

但這樣的貝殼很少見,並不是什麼你的無論如何,程序都需要。

將輸入傳送到您的程式

如果您希望您的程式從檔案描述符 2 讀取內容,則可以讀取某些內容其他與從終端機相比,您當然可以重定向該檔案描述符。你可以使用正常的輸入重定向語法(<shell 中的運算子),但程式中的程式庫,甚至您在其他地方編寫的其他程式碼,都會假設它們可以寫入此檔案描述符。

shell 允許您使用<>重定向運算子來明確開啟檔案以進行讀取和寫入。這是您在重定向程式的檔案描述符 2 時使用的。

./myprogram 2<>filename

除了 shell 重定向之外,還有很多工具可以操作檔案描述符。例如:Laurent Bercot 的鍊式載入redirfd工具,與 execline 一起提供,這個重定向看起來更像你的假設:

redirfd -u 2 filename ./myprogram

Bourne Again 和 Z shell(但不是 Almquist shell)等 shell 語法也為文件描述符 2 提供「此處文件」和「此處字串」。只讀在這種情況下通過這些外殼。

./myprogram 2<<< "here string"

答案2

stderr是用來寫的,不是用來讀的。有時它是一個dup重複stdin(例如,當所有 3 個輸入/輸出/錯誤都連接到終端時)。要讀取另一個程式的 stderr,您可以將該程式的 stderr 重定向到另一個程式的 stdin。

例如 指向stdout一個文件,然後stderr指向./myprograms's stdin

command 2>&1 >a_file | ./myprogram

答案3

bash使用像and 之類的 shell zsh(但不是普通的 POSIX sh),您可以透過 將一個程式的標準錯誤重新導向到另一個程式的標準輸入firstprogram 2> >(second program)

例子:

$ perl -E 'say "perl stdout"; warn "perl stderr\n"' 2> >(awk '{print "awk", $0}')
perl stdout
awk perl stderr

答案4

要讓 shell 設定輸入重定向stderr,您可以使用<,<<<<<並在檔案描述符編號前加上前綴:

./myprog 2< somefile.txt

或者

./myprog 2<<< "some text"

但如果你stderr像那樣重定向,程式就不能輸出到它,這意味著您不會看到程式(或其使用的任何庫)可能嘗試列印的任何錯誤訊息,此外,程式還會因嘗試寫入這些訊息而出現錯誤。

您可能需要重新考慮是否有其他方法可以完成您正在做的事情。至少,如果想法是為程式提供一些輸入,請考慮使用例如 fd 3。

相關內容