2010-10-29 136 views
8

我寫了一個代碼來獲得一個運行時錯誤故意:關於標準輸出/標準錯誤重定向

int main() 
{ 
int a=5; 
printf("Hello World\n"); 
printf("a=%s\n", a); 
} 

它提供:

$ ./error.o 
Hello World 
Segmentation Fault 
$ 

現在,記錄運行時錯誤,我做的:

$ ./error.o > so.txt 
$ ./error.o &> soe.txt 

但這兩個文件都是空的。爲什麼?

編輯:

實際上我正在編寫的遠程彙編和C程序的執行腳本。從我得到的答案Segmentation Fault不是程序的錯誤輸出。那麼,有沒有辦法來捕捉那個輸出?此外,該程序只是一個示例,所以我不能添加這些語句。線路緩衝可以通過其他方式進行重定向嗎?

+0

%s是錯誤的。 – Nyan 2010-10-29 09:11:45

+0

@Nyan:我這樣做是故意得到seg-fault。我正在編寫一個腳本來捕獲執行錯誤,所以這只是模仿將來可能對我的腳本的輸入。 – lalli 2010-10-29 09:24:47

+1

您編輯了關於如何爲重定向文件啓用行緩衝的問題。我更新了我的答案以添加信息。 – jjrv 2010-10-29 09:31:39

回答

10

so.txt是空的,因爲標準輸出沒有得到崩潰,因此緩衝的內容丟失之前沖刷。如果添加:fflush(stdout);在printf命令之間,它將包含預期的文本。

您的soe.txt缺少「Segmentation Fault」消息,因爲它是由shell打印的,而不是由您的程序打印的,因此不屬於您的程序輸出的重定向部分。

如果您不能修改代碼,你可以通過欺騙程序認爲它打印到一個TTY打開行緩衝。創建腳本error.sh:

#!/bin/sh 
./error.o 

然後做一個搭配chmod + X error.sh並調用它在Linux上:

script soe.txt -c ./error.sh 

或者這樣的OS X:

script soe.txt ./error.sh 

確切的輸出有點系統相關,但可能包含「Hello World」和「Segmentation Fault」。

也可以考慮添加適當的#include線和返回從主的值。

+0

有沒有辦法在文件中捕獲'Segmentation fault'?我可以在bash內運行另一個bash嗎? – lalli 2010-10-29 08:53:05

+0

是的,答案已更新。 – jjrv 2010-10-29 08:54:40

+0

啊,謝謝..... – lalli 2010-10-29 09:01:28

7

因爲分割故障是嚴重。緩衝區不會被刷新,你的進程會被猛烈關閉。

你看到的文字時不進行重新定向運行的原因是標準輸出行緩衝(即全緩衝僅用於如果該設備可以被確定爲不是一個交互ISO C任務)。換句話說,只要看到換行符就會刷新,發生之前您的無效的參考。

但由於文件輸出未行緩衝,信息仍然在等待當你的程序的宇宙是從它下面拽出被髮送出去。

雖然這種支持是實現定義的,你可以設置一個特定的文件句柄使用setvbuf_IOLBF模式行緩衝,是這樣的:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ); 

main()開始 - 這樣可以節省大量輸入每條輸出線都必須輸入fflush

+0

有沒有辦法用重定向緩衝行? – lalli 2010-10-29 08:54:12

+0

謝謝,我猜想我必須愚弄調度程序,然後...... – lalli 2010-10-29 09:02:44

+0

@lalli,是的,你可以,我經常這樣做,以避免必須在所有地方放置'fflush()'。查看'setvbuf()'的更新。 – paxdiablo 2010-10-29 09:03:09

3

我想這應該這樣做:對於int

echo ./error.o | sh > error.txt 
+0

哦,這有助於,謝謝.. – lalli 2010-10-29 09:03:05

相關問題