2015-08-29 20 views
1

如果我使用puts,我可以標準輸出重定向預期:爲什麼stdout重定向在put函數中工作但不能寫入?

#include <stdio.h> 

int main() { 
    char *s = "hello world"; 
    puts(s);  
    return 0; 
} 

重定向它:

$ gcc -Wall use_puts.c 
$ ./a.out 
hello world 
$ ./a.out > /dev/null 

但是,如果我用write寫到標準輸出,shell重定向不起作用:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

int main() { 
    char *s = "hello world\n"; 
    write(0, s, strlen(s)); 
    return 0; 
} 

重定向它:

$ gcc -Wall use_puts.c 
$ ./a.out 
hello world 
$ ./a.out > /dev/null 
hello world 

這是爲什麼?在這種情況下,如何將寫入重定向到stdout?

+2

如果你在Linux下並且用'puts()'版本使用'strace ./.a.out',你會發現'puts()'調用帶有文件描述符1而不是0的'write()'。 –

回答

5

write語句寫入標準輸入而不是標準輸出。我很驚訝它的作品。

通常這就是爲什麼你應該使用常量,而不是文字值,因爲它是不太容易出現這種類型的錯誤:

write(STDOUT_FILENO, s, strlen(s)); 

STDOUT_FILENOSTDIN_FILENOSTDERR_FILENOunistd.h定義)

+2

它的工作原理是沒有重定向,他從終端上運行,所以stdin,stdout和stderr都是去終端 - 終端可能是開放的讀/寫,所以你可以寫信給他們中的任何一個(並從其中任何一個讀取)。 ***不要***依靠;該代碼需要修復才能寫入stdout。 –

+1

是的,我只是想* stdin *通常會被限制爲只讀。讓我感到驚訝。 – larsks

+0

這是一個很自然的假設,但我猜測許多UN * Xes上的登錄過程/終端仿真器啓動過程只是打開一個tty而不是兩個需要防止寫入stdin或從stdout/stderr讀取。 –

3

您寫入標準輸入,我想你想這

​​
相關問題