1. 程式人生 > >popen和pclose

popen和pclose

文章出處:http://coderworm.com/unix/2013/12/16/unix-process-communicate-b.html

上邊介紹了unix程序通訊的其中一個方式:pipe, 不過如果直接使用原生的函式的話,需要我們自己去fork程序,關閉管道的不使用端等等。這裡,介紹標準I/O庫提供的兩個函式:

FILE* popen(const char *cmdstring, const char *type);
				//成功返回檔案指標,出錯則返回NULL
int pclose(FILE *fp);
				//返回cmdstring的終止狀態,出錯則返回-1  

函式popen會先執行fork,然後呼叫exec以執行cmdstring(通常是執行一個shell以執行命令),並且返回一個標準I/O檔案指標。type標識返回的檔案指標可以進行的操作。

  1. 如果type為“r”,則檔案指標連線到cmdstring的標準輸出;即返回的檔案指標是可讀的。
  2. 如果type為”w”,則檔案指標連線到cmdstring的標準輸入;即返回的檔案指標是可寫的。

pclose函式關閉標準I/O流,等待命令執行結束,然後返回shell的終止狀態。通常,在pclose內部,會呼叫waitpid等待子程序執行結束,不過,通過我自己測試發現,如果子程序發生異常,那麼則waitpid不會阻塞而立即返回。

下邊我們看一個示例程式:

//test.sh
#!/bin/bash
echo "before sleep"
sleep 3

//popentest.c
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char **argv) {
	char *filename = argv[1];
	char *mode = argv[2];
	printf("execute filename:%s, %s\n", filename, mode);
	FILE *fl = popen(filename, mode);
	int t = pclose(fl);
	if(WIFEXITED(t)) {
	    printf("exit status:%d\n", WEXITSTATUS(t)); 
	}
	return 0;
} 

當我們編譯程式執行時:
$ gcc -o p popentest.c
$ ./p "sh test.sh" r 

當我們上邊這種方式執行的時候,很可能程式會立即返回並不會等待test.sh檔案執行結束。在我自己的機器上(Ubuntu 12.04.3 LTS),輸出:
exit status:141

141說明子程序接受了SIGPIPE訊號,那麼為什麼會收到SIGPIPE呢?

首先,我們以讀的方式開啟管道,則返回的fl指標連線到子程序的標準輸出;其次,我們知道,父程序在fork了子程序後,它們的執行次序是不確定的,在上邊的例子中,popen函式返回後,立即執行pclose,我們知道在pclose會關閉fl指標關聯的描述符。很可能此時子程序中執行的shell命令echo,此時的描述符已被關閉,所以核心會發送SIGPIPE訊號然後子程序退出。所以此時在呼叫waitpid則不會阻塞而立即返回。

-EOF-


相關推薦

基於管道的popenpclose函式

基於管道的popen和pclose函式 https://my.oschina.net/renhc/blog/35116   標準I/O函式庫提供了popen函式,它啟動另外一個程序去執行一個shell命令列。 這裡我們稱呼叫popen的程序為父程序,由popen啟動的程序稱

popenpclose

文章出處:http://coderworm.com/unix/2013/12/16/unix-process-communicate-b.html 上邊介紹了unix程序通訊的其中一個方式:pipe, 不過如果直接使用原生的函式的話,需要我們自己去fork程序,關閉管道的

popenpclose命令

popen可以像system命令一樣去在程式裡面去呼叫另一個程式,區別在於popen命令可以獲取被呼叫程式的輸出資料,使用者可以像操作檔案一樣去讀取這些資料,在對資料使用結束後通過pclose函式關閉檔案流。  #include <stdio.h> int m

Linux popenpclose函式

popen和pclose 標頭檔案 #include <stdio.h> 函式原型 FILE *popen(const char *command, const char *type)

linux c之通過popenpclose函式建立管道執行shell 執行命令使用總結

1、函式介紹  popen 和 pclose 函式        操作是建立一個管道連結到另一個程序,然後讀其輸出或向其輸入端傳送資料。標準 I/O 庫提供了兩個函式 popen 和 pclose 函式,這兩個函式實現的操作是:建立一個管道,呼叫 fork 建立一個子程序

popenpclose詳解及例項

popen函式是標準c提供的一個管道建立函式,其內部操作主 要是建立一個管道,呼叫fork建立子程序,關閉不需用的檔案描述符,呼叫exec函式族執行popen的第一個引數。然後等到關閉。 也就是說我們可以傳遞一個命令(ls -l......)或一個可執行

程序間通訊--popen函式pclose函式blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=25940216&id=3206312

因為一個普遍的操作是為另一個程序建立一個管道,或者讀它的輸出或向它傳送輸入,所以標準I/O庫歷史上提供了popen和pclose函式。這兩 個函式處理我們自己一直在做的髒活:建立一個管道、fork一個子程序、關閉管道無用的端,執行一個外殼來執行這個命令,等待命令終止。 #include <st

popensystem問題

popen和system問題 1. 問題描述 C的程式碼裡面去呼叫命令啟動一個shell指令碼,分別使用了下面兩個途徑。 其中一個是: func1(cmd) { popen(cmd,type); pclose(); } 另一個是: func2() { system(

C 語言popen函數,實現shell讀取內容

原型 stream printf fclose strong get cmd 包含 文件 1. popen()函數 頭文件:#include <stdio.h> 函數原型:FILE * popen(const char * command, const char

python筆記16-執行cmd指令(os.systemos.popen

PE () ima 常用 字符串 ces 寫入內容 控制臺 close os.system 1.如果想在cmd執行python腳本,可以直接用如下指令 python [xx.py絕對路徑] 比如我寫了個hello.py的腳本,在腳本裏面寫入內容:print("hello

os.systemos.popen函數

os.popen函數os.system和os.popen函數: python調用shell命令有2種方法:os.system()和os.popen() os.system()的返回值只會有0(成功),1,2;os.popen()會把執行命令的輸出作為值返回,可實現一個“管道”,從這個命令獲取的值可以繼續被調用

Linux 調研popen/system, 理解這兩個函式fork的區別.

自己的總結:           1.popen是並行(最後子程序是由pclose回收),system是序列(會等待子程序做完事,然後收拾)。           2.system() 在等待命令終止時將忽略SIGINT 和SIGQUIT 訊號,同時阻塞SIGCHLD

Python_cmd的各種實現方法及優劣(subprocess.Popen, os.systemcommands.getstatusoutput)

轉自:http://blog.csdn.net/menglei8625/article/details/7494094 目前我使用到的python中執行cmd的方式有三種: 1. 使用os.system("cmd") 這是最簡單的一種方法,特點是執行的時候程式會打出c

python os.system()os.popen()

1》python呼叫Shell指令碼,有兩種方法:os.system()和os.popen(), 前者返回值是指令碼的退出狀態碼,後者的返回值是指令碼執行過程中的輸出內容。 >>>help(os.system) Help on built-in funct

popen()函式執行指令碼,要用pclose()函式關閉

就像百度百科中所說popen()函式通過建立一個管道,呼叫fork()產生一個子程序,執行一個shell以執行命令來開啟一個程序。這個管道必須由pclose()函式關閉。 其中”必須由pclose()函式關閉“是一個容易被忽視的點,這不光光浪費資源的問題,更涉及到子程序的週

Linux中的popen函式system函式

說在前面:在實際程式設計中儘量減少使用system函式。int system(const char *command);說明: system()通過呼叫/ bin / sh -c命令執行命令中指定的命令,並在命令完成後返回。在執行該命令期間,SIGCHLD將被阻塞,並且SIG

Python Popen communicate()wait()使用上的區別

使用 subprocess 模組的 Popen 呼叫外部程式,如果 stdout 或 stderr 引數是 pipe,並且程式輸出超過作業系統的 pipe size時,如果使用 Popen.wait() 方式等待程式結束獲取返回值,會導致死鎖,程式卡在 wait() 呼叫上

管道之popen,pclose函式

 方法6的popen,pclose函式: #include <stdio.h> FILE *popen(const char *cmdstring, const char *type

python中的os.system()os.popen()區別

python呼叫Shell指令碼或者是呼叫系統命令,有兩種方法:os.system(cmd)或os.popen(cmd),前者返回值是指令碼的退出狀態碼,後者的返回值是指令碼執行過程中的輸出內容。實際使用時視需求情況而選擇。 現假定有一個shell指令碼test.sh:

Linux函式popen/pclose學習

本文針對專案中用到的幾個函式進行詳細分析,並儘可能的新增示例進行驗證學習。比如fcntl/ioctl函式、system/exec函式、popen/pclose函式、mmap函式等。 重點參考了《UNP》和《Linux程式設計》第四版。 一、概念