TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年2月6日 星期三

Order of I/O redirecting

在shell使用的I/O重導,其行為其實還有很多有趣的部分。一般常使用的就是<>,但是它們其實不只能重導stdin和stdout,重導的方向也不只有檔案或裝置而已。
<>其實前方可以加數字,就是file descripter,若不特別指明,那麼<預設會是0<>預設是1>,其中0即為stdin的file descripter,1為stdout的file descripter[?],而2就是stderr了。[?]
因此I/O重導的真正格式為:
M<N
M>N
其中M為file descripter,N為某個檔案[?]。而如果要把fd導向給另一個fd,就要用下列格式:
M>&N
其中M和N都是file descripter。
然而依然要小心一個小問題,就是重導的次序不同,效果也會有不同。
考慮以下的狀況:
$ cat > test.c
#include <stdio.h>
int main( int argc, char * argv[] ) {
    puts( "This is stdout." );
    fputs( stderr, "This is stderr." );
    return 0;
}
^D
$ gcc test.c -o test
$ ./test >output.txt 2>&1
$ ./test 2>&1 >output.txt
有趣的是,第一次在螢幕上什麼都沒顯示,而output.txt裡會找到那二個句子,但是第二次卻會在螢幕上顯示`This is stderr.',output.txt只有`This is stdout.'。表面看起來結果至少要相反才對呀?
因為第一種寫法,代表stdout先被dup2到output.txt,然後stderr才被dup2到被更改過的stdout,因此兩個都會進入output.txt。
而第二種寫法,則是stderr dup2到stdout,這時stdout還是連接在console上,不管之後stdout有沒有被更動,它就是會輸出到console,所以會變成stderr > console,stdout > output.txt。

沒有留言:

張貼留言