我們支持,linux常用的調(diào)用外部指令,有兩個接口ppen和system
popen的使用
函數(shù)原型
#include <stdio.h>
FILE * popen ( const char * command , const char * type );
int pclose ( FILE * stream );
說明
popen() 函數(shù)通過創(chuàng)建一個管道,調(diào)用 fork 產(chǎn)生一個子進程,執(zhí)行一個 shell 以運行命令來開啟一個進程。這個進程必須由 pclose() 函數(shù)關(guān)閉,而不是 fclose() 函數(shù)。pclose() 函數(shù)關(guān)閉標準 I/O 流,等待命令執(zhí)行結(jié)束,然后返回 shell 的終止狀態(tài)。如果 shell 不能被執(zhí)行,則 pclose() 返回的終止狀態(tài)與 shell 已執(zhí)行 exit 一樣。
type 參數(shù)只能是讀或者寫中的一種,得到的返回值(標準 I/O 流)也具有和 type 相應的只讀或只寫類型。如果 type 是 "r" 則文件指針連接到 command 的標準輸出;如果 type 是 "w" 則文件指針連接到 command 的標準輸入。
command 參數(shù)是一個指向以 NULL 結(jié)束的 shell 命令字符串的指針。這行命令將被傳到 bin/sh 并使用-c 標志,shell 將執(zhí)行這個命令。
popen 的返回值是個標準 I/O 流,必須由 pclose 來終止。前面提到這個流是單向的。所以向這個流寫內(nèi)容相當于寫入該命令的標準輸入;命令的標準輸出和調(diào)用 popen 的進程相同。與之相反的,從流中讀數(shù)據(jù)相當于讀取命令的標準輸出;命令的標準輸入和調(diào)用 popen 的進程相同。
返回值
如果調(diào)用 fork() 或 pipe() 失敗,或者不能分配內(nèi)存將返回NULL,否則返回標準 I/O 流。
返回錯誤
popen 沒有為內(nèi)存分配失敗設(shè)置 errno 值。
如果調(diào)用 fork() 或 pipe() 時出現(xiàn)錯誤,errno 被設(shè)為相應的錯誤類型。
如果 type 參數(shù)不合法,errno將返回EINVAL。
使用舉例
/**運行命令
*1. cmd 要執(zhí)行的命令
*2. 參數(shù)type可使用“r”代表讀取,“w”代表寫入。
*/
int runShell(const char *cmd,const char *type,char *resultBuffer,int len)
{
int ret;
FILE * pp=popen(cmd,type);
ret = fread ( resultBuffer, 1, len, pp );
pclose(pp);
return ret;
}
如果想看到標準出錯的信息呢?
只需在命令中加入重定向 例如:
cp -f 2>&1
system調(diào)用
system()會調(diào)用fork()產(chǎn)生子進程,由子進程來調(diào)用/bin/sh-c string來執(zhí)行參數(shù)string字符串所代表的命令,此命>令執(zhí)行完后隨即返回原調(diào)用的進程。在調(diào)用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。
返回值
=-1:出現(xiàn)錯誤
=0:調(diào)用成功但是沒有出現(xiàn)子進程
>0:成功退出的子進程的id
命令執(zhí)行的返回值獲取可參考我的如下例程:
int mysystem(char *cmd)
{
pid_t status;
status = system(cmd);
if (-1 == status)
{
D("system error! status=%d\n",status);
}
else
{
if (WIFEXITED(status))
{
if (0 == WEXITSTATUS(status))
{
D("run shell script successfully.\n");
return 0;
}
else
{
E("run script fail, script exit code: %d\n", WEXITSTATUS(status));
return WEXITSTATUS(status);
}
}
else
{
D("exit %d\n", WEXITSTATUS(status));
return WEXITSTATUS(status);
}
}
}
system調(diào)用總是返回-1的原因
返回-1的原因是因為進程將SIGCHLD屏蔽了!
確實我的程序在main函數(shù)里面就調(diào)用signal(SIGCHLD, SIG_IGN);將SIGCHLD屏蔽了!
system的調(diào)用過程主要是調(diào)三個函數(shù)
- fork()
- execl()
- wait()
wait需要依賴SIGCHLD信號,所以屏蔽了SIGCHLD信號就永遠得不到system正確的返回值了!