perl 實現shell重定向功能

2021-06-10 01:33:11 字數 2058 閱讀 7167

許多unix shell可以把標準輸出檔案(stdout)和標準錯誤檔案(stderr)都重定向到同乙個檔案,例如在bourne shell(sh)中,命令

$ foo > file1 2>&1

執行命令foo並把輸出到標準輸出檔案和標準錯誤檔案的內容存貯到檔案file1中。下面是用perl實現這一功能的例子:

1: #!/usr/local/bin/perl

2: 3: open (stdout, ">file1") || die ("open stdout failed");

4: open (stderr, ">&stdout") || die ("open stderr failed");

5: print stdout ("line 1\n");

6: print stderr ("line 2\n");

7: close (stdout);

8: close (stderr);

執行後,檔案file1中的內容為:

line 2

line 1

可以看到,這兩行並未按我們想象的順序存貯,為什麼呢?我們來分析一下這段程式。

第3行重定向標準輸出檔案,方法是開啟檔案file1將它與檔案變數stdout關聯,這也關閉了標準輸出檔案。第4行重定向標準錯誤檔案,引數》&stdout告訴perl直譯器使用已開啟並與stdout關聯的檔案,即檔案變數stderr指向與stdout相同的檔案。第5、6行分別向stdout和stderr寫入資料,因為這兩個檔案變數指向同乙個檔案,故兩行字串均寫到檔案file1中,但順序卻是錯誤的,怎麼回事呢?

問題在於unix對輸出的處理上。當使用print(或其它函式)寫入stdout等檔案時,unix作業系統真正所做的是把資料拷貝到一片特殊的記憶體即緩衝區中,接下來的輸出操作繼續寫入緩衝區直到寫滿,當緩衝區滿了,就把全部資料實際輸出。象這樣先寫入緩衝區再把整個緩衝區的內容輸出比每次都實際輸出所花費的時間要少得多,因為一般來說,i/o比記憶體操作慢得多。

程式結束時,任何非空的緩衝區都被輸出,然而,系統為stdout和stderr分別維護一片緩衝區,並且先輸出stderr的內容,因此存貯在stderr的緩衝區中的內容line 2出現在存貯在stdout的緩衝區中的內容line 1之前。

--------(我覺得解釋有問題,perl  的print函式是有緩衝的,是行緩衝,所以碰到\n,print就立即把「標準輸出」列印出來了,如果內容沒有碰到換行,先存在緩衝區,等到緩衝區滿了再列印。然而錯誤輸出是沒有緩衝的,所以就立即列印出來了)

為了解決這個問題,可以告訴perl直譯器不對檔案使用緩衝,方法為:

1、用select函式選擇檔案

2、把值1賦給系統變數$|

系統變數$|指定檔案是否進行緩衝而不管其是否應該使用緩衝。如果$|為非零值則不使用緩衝。$|與系統變數$~和$^協同工作,當未呼叫select函式時,$|影響當前預設檔案。下例保證了輸出的次序:

1 : #!/usr/local/bin/perl

2 : 

3 : open (stdout, ">file1") || die ("open stdout failed");

4 : open (stderr, ">&stdout") || die ("open stderr failed");

5 : $| = 1;

6 : select (stderr);

7 : $| = 1;

8 : print stdout ("line 1\n");

9 : print stderr ("line 2\n");

10: close (stdout);

11: close (stderr);

程式執行後,檔案file1中內容為:

line 1

line 2

第5行將$|賦成1,告訴perl直譯器當前預設檔案不進行緩衝,因為未呼叫select,當前的預設檔案為重定向到檔案file1的stdout。第6行將當前預設檔案設為stderr,第7行又設定$|為1,關掉了重定向到file1的標準錯誤檔案的緩衝。由於stdout和stderr的緩衝均被關掉,向其的輸出立刻被寫到檔案中,因此line 1出現在第一行。

shell重定向輸入

這條命令的作用是將標準輸出1重定向到 dev null中。dev null代表linux的空裝置檔案,所有往這個檔案裡面寫入的內容都會丟失,俗稱 黑洞 那麼執行了 dev null之後,標準輸出就會不再存在,沒有任何地方能夠找到輸出的內容。錯誤輸出將會和標準輸出輸出到同乙個地方,linux在執行sh...

shell中輸入重定向,輸出重定向,管道

什麼是檔案描述符 1 程序中開啟乙個檔案就會有乙個檔案描述符 2 檔案描述符是乙個非負整數 3 系統為每乙個程序維護乙個檔案描述符表 程序級檔案描述符 4 同乙個程序裡面不同檔案描述符可以對應同乙個檔案 乙個檔案被開啟多次 5 不同程序的檔案描述符可以相同 不影響 可以指向同乙個檔案,也可以指向不同...

shell輸出重定向操作

在linux shell執行命令時,每個程序都和三個開啟的檔案相聯絡,並使用檔案描述符來引用這些檔案。由於檔案描述符不容易記憶,shell同時也給出了相應的檔名。標準輸入 0 預設是鍵盤,為0時是檔案或者其他命令的輸出 標準輸出 1 預設是螢幕,為1時是檔案 標準出錯 2 預設是螢幕,為2時是檔案 ...