進程在啟動後會自動的打開3個文件:標准輸入、標准輸出和標准錯誤輸出分別對應文件描述符0、1、2。對於每個進程他們都都維護了一張文件描述符表(file descriptor table),通常fd(file discriptor同下文) 的取值范圍是0-1023(可以通過ulimit -n命令查看,當然這不是標准,可以自行修改,但是這通常已經夠用了)。每個文件描述符表項都有一個文件指針,指向一張打開文件表(open file table),這張表是內核級的,意思就是說可以存在兩個進程中的fd指向同一個打開文件表項。比如一個進程打開文件之後通過fork()產生了一個子進程,那麼就會出現兩個進程中的fd指向同一個打開文教表表項的情況。指向同一個打開文件表表項意味著這樣的fd擁有同樣的offset以及status flags。如下圖所示:
關於重定向
在bash中,重定向的語法用‘>’和'<'表示,如“2>&1”,意思就是把標准錯誤輸出(文件描述符為2)重定向(redirection)到標准輸出(文件描述符為1)。具體可以這樣實現:
當然,除了使用文件描述符之外也可以使用文件名作為重定向的“方向”,如“ls > file ”,就是把ls的標准輸出將結果重定向到file的輸入之中。於是所有到標准輸出的輸出都被重定向到了file的輸入中,file的內容便再現了ls命令的結果。
其實我以為對重定向的理解,關鍵不在代碼的實現,當知道了原理之後,腦中有了一個具體的概念,剩下的事只是“看圖說話”了,也許就是所謂的事半功倍的效果吧。