C程序調用shell腳本共有三種法子 :system()、popen()、exec系列函數call_exec1.c ,內容爲:
system() 不用你本身去產生進程,它已經封裝了,直接加入本身的命令
exec 須要你本身 fork 進程,而後exec 本身的命令
popen() 也能夠實現執行你的命令,比system 開銷小html
一、system(執行shell 命令)web
相關函數 fork,execve,waitpid,popen
表頭文件 #include<stdlib.h>
定義函數 int system(const char * string);
函數說明 system()會調用fork()產生子進程,由子進程來調用/bin/sh-c
string來執行參數string字符串所表明的命令,此命令執行完後隨
即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時
擱置,SIGINT和SIGQUIT 信號則會被忽略。
返回值 若是system()在調用/bin/sh時失敗則返回127,其餘失敗緣由返回-
1。若參數string爲空指針(NULL),則返回非零值。若是system()調
用成功則最後會返回執行shell命令後的返回值,可是此返回值也有
可能爲system()調用/bin/sh失敗所返回的127,所以最好能再檢查
errno 來確認執行成功。
附加說明 在編寫具備SUID/SGID權限的程序時請勿使用system(),system()會
繼承環境變量,經過環境變量可能會形成系統安全的問題。shell
範例:安全
#include<stdlib.h>bash
main()函數
{spa
system(「ls -al /etc/passwd /etc/shadow」);指針
}code
二、popen(創建管道I/O)orm
相關函數 pipe,mkfifo,pclose,fork,system,fopen
表頭文件 #include<stdio.h>
定義函數 FILE * popen( const char * command,const char * type);
函數說明 popen()會調用fork()產生子進程,而後從子進程中調用/bin/sh -c
來執行參數command的指令。參數type可以使用「r」表明讀取,「w」
表明寫入。依照此type值,popen()會創建管道連到子進程的標準輸
出設備或標準輸入設備,而後返回一個文件指針。隨後進程即可利
用此文件指針來讀取子進程的輸出設備或是寫入到子進程的標準輸
入設備中。此外,全部使用文件指針(FILE*)操做的函數也均可以使
用,除了fclose()之外。
返回值 若成功則返回文件指針,不然返回NULL,錯誤緣由存於errno中。
錯誤代碼 EINVAL參數type不合法。
注意事項 在編寫具SUID/SGID權限的程序時請儘可能避免使用popen(),popen()
會繼承環境變量,經過環境變量可能會形成系統安全的問題。
範例:
#include<stdio.h>
main()
{
FILE * fp;
char
buffer[80];
fp=popen(「cat /etc/passwd」,」r」);
fgets(buffer,
sizeof
(buffer),fp);
printf(「%s」,buffer);
pclose(fp);
}
|
執行 root :x:0 0: root: /root: /bin/bash
三、使用vfork()新建子進程,而後調用exec函數族
#include<unistd.h>
main()
{
char * argv[ ]={「ls」,」-al」,」/etc/passwd」,(char*) };
if(vfork() = =0)
{
execv(「/bin/ls」,argv);
}else{
printf(「This is the parent process\n」);
}
}