标準i/o函數庫提供了popen函數,它啟動另外一個程序去執行一個shell指令行。
這裡我們稱調用popen的程序為父程序,由popen啟動的程序稱為子程序。
popen函數還建立一個管道用于父子程序間通信。父程序要麼從管道讀資訊,要麼向管道寫資訊,至于是讀還是寫取決于父程序調用popen時傳遞的參數。下在給出popen、pclose的定義:
下面通過例子看下popen的使用:
假如我們想取得目前目錄下的檔案個數,在shell下我們可以使用:
我們可以在程式中這樣寫:
編譯并執行:
輸出結果
上面popen隻捕獲了command的标準輸出,如果command執行失敗,子程序會把錯誤資訊列印到标準錯誤輸出,父程序就無法擷取。比如,command指令為“ls nofile.txt” ,事實上我們根本沒有nofile.txt這個檔案,這時shell會輸出“ls: nofile.txt: no such file or directory”。這個輸出是在标準錯誤輸出上的。通過上面的程式并無法擷取。
注:如果你把上面程式中的command設成“ls nofile.txt”,編譯執行程式你會看到如下結果:
需要注意的是第一行輸出并不是父程序的輸出,而是子程序的标準錯誤輸出。
有時子程序的錯誤資訊是很有用的,那麼父程序怎麼才能擷取子程序的錯誤資訊呢?
這裡我們可以重定向子程序的錯誤輸出,讓錯誤輸出重定向到标準輸出(2>&1),這樣父程序就可以捕獲子程序的錯誤資訊了。例如command為“ls nofile.txt 2>&1”,輸出如下:
指令【ls nofile.txt 2>&1】 輸出【ls: nofile.txt: no such file or directory】
指令【ls nofile.txt 2>&1】子程序結束狀态【256】指令傳回值【1】
附:子程序的終止狀态判斷涉及到的宏,設程序終止狀态為status.
wifexited(status)如果子程序正常結束則為非0值。
wexitstatus(status)取得子程序exit()傳回的結束代碼,一般會先用wifexited 來判斷是否正常結束才能使用此宏。
wifsignaled(status)如果子程序是因為信号而結束則此宏值為真。
wtermsig(status)取得子程序因信号而中止的信号代碼,一般會先用wifsignaled 來判斷後才使用此宏。
wifstopped(status)如果子程序處于暫停執行情況則此宏值為真。一般隻有使用wuntraced 時才會有此情況。
wstopsig(status)取得引發子程序暫停的信号代碼,一般會先用wifstopped 來判斷後才使用此宏。