
這是我從我寫的 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/tty
POSIX 已經存在很長時間了,超過 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。