system - execute a shell command
#include <stdlib.h>
int system (const char *command);
描述
The system() uses fork to create a child process that executes a command specified in command using execl as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
and returns after the command has been completed.
During excution of the comman, SIGCHLD will be bocked, and SIGINT and SIGQUIT will be ignored.
If command is NULL, the system() returns a status indicating whether a shell is available on the system.
注意:system在執行完command后才會返回。易造成system進程阻塞,可在command后增加&,以讓system立即返回。
返回值
》假如command是NULL,非零值指示shell(執行cmd的/bin/sh)可用,0指示shell不可用。一般情況都返回非0(NULL時),因為系統shell可用。
》假如chilid進程創建失敗(fork失敗),或child進程狀態不能獲取(不知fork進程是否創建成功,如內存不足等或未知原因),返回-1。一般不會出現此情況,但應判斷此異常情況,判斷返回值不為-1。
》假如shell不能在child子進程中執行,此時類似子進程調用_exit(127)退出。比如執行的shell命令不存在。system返回0x7F00(32512),shell退出代碼為127.
》system調用成功,返回值是執行command的shell的結束狀態(shell的退出狀態是shell執行的最后command的終止狀態)。
最后兩情況,返回值是“wait status"。wait status可以用waitpid宏檢測(如WIFEXITED(),WEXITSTATUS()等)。
system() does not affect the wait status of any other children.
注意
As mentioned, system() ignores SIGINT and SIGQUIT. This may make programs that call it from a loop uninterruptible, unless they take care themselves to check the exit status of the child. E.g.
while(something) {
int ret = system("foo");
if(WIFSIGNALED(ret) && (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT))
break;
}
It is possible for the shell command to return 127, so that code is not a sure indication that the execve call failed.
一般應用舉例(system執行時,fork必須成功(不能返回-1);一般shell成功返回0,判斷不為0退出):
ret = system(cmd); if(ret < 0){ exit (1); } if(WEXITSTATUS(ret) != 0){ printf("cmd failed.\n"); exit(1); }
system立刻返回的舉例:
#include <stdio.h> #include <stdlib.h> #include <wait.h> #define CMD "./hao.sh&" int main(int argc, char *argv[]) { int ret = 0; if(argc == 1){ ret = system(CMD); // ret = system(NULL); } else { ret = system(argv[1]); } printf("return:%d\n", ret); if(ret == 0){ printf("Success\n"); } else { printf("Fail\n"); if(WIFEXITED(ret)){ printf("error status:%d\n", WEXITSTATUS(ret)); } if(WIFSIGNALED(ret)){ printf("error signal:%d\n", WTERMSIG(ret)); } } return 0; }