Use popen
if you want to run a shell command and want the parent process to be able to talk to the child. (It hooks the child's input or output up to the stream you get back.) Otherwise, prefer the exec
family of functions (likely in conjunction with fork
); exec
'd processes inherit most open file descriptors (including stdin, stdout, and stderr), so you can hook input and output up to whatever you like...plus, there are fewer security implications.linux
system
is generally best avoided unless you have to run shell commands. It spawns a shell to run the command, and the shell can parse the command any way it likes. In particular, certain environment variables (like $IFS
and/or $PATH
) can be modified in such a way as to cause the parent to execute programs you never intended it to. Although popen
appears to do the same thing, it at least provides functionality that makes it worthwhile in the general case.shell
---------------------------------------------------------------------------------------------------------------------------------------------------------編程
問題:ubuntu
1. system能夠直接運行帶參數的shell腳本,特別是數字參數如,system("/bin/bash ~/test.sh 100 10"); 那麼execlp怎麼作呢?vim
轉自:http://blog.csdn.net/luokehua789789/article/details/53117904數組
#!bin/bash #test.sh echo $HOME
#include /*This program is used to test function system*/ void main() { int rv = system("~/myprogram/test.sh");
if (WIFEXITED(rv))
{
printf("subprocess exited, exit code: %d\n", WEXITSTATUS(rv));
if (0 == WEXITSTATUS(rv))
{
// if command returning 0 means succeed
printf("command succeed");
}
else
{
if(127 == WEXITSTATUS(rv))
{
printf("command not found\n");
return WEXITSTATUS(rv);
}
else
{
printf("command failed: %d\n", strerror(WEXITSTATUS(rv)));
return WEXITSTATUS(rv);
}
}
}
else
{
printf("subprocess exit failed");
return -1;
}安全
}bash
xiakeyou@ubuntu:~/myprogram$ gcc systemtest.c -o systemtest xiakeyou@ubuntu:~/myprogram$ ./systemtest /home/d/e/xiakeyou xiakeyou@ubuntu:~/myprogram$
#include main() { FILE * fp; charbuffer[80]; fp=popen(「~/myprogram/test.sh」,」r」); fgets(buffer,sizeof(buffer),fp); printf(「%s」,buffer); pclose(fp); }
xiakeyou@ubuntu:~/myprogram$ vim popentest.c xiakeyou@ubuntu:~/myprogram$ gcc popentest.c -o popentest xiakeyou@ubuntu:~/myprogram$ ./popentest /home/d/e/xiakeyou xiakeyou@ubuntu:~/myprogram$
popen函數執行命令後,返回一個指向該命令輸出的文件句柄,接下來就能夠用fgets等文件操做函數去讀取輸出結果。app
#include FILE *popen(const char *command, const char *type); int pclose(FILE *stream);
例如less
#include #include int main(int argc,char*argv[]){ FILE *fstream=NULL; char buff[1024]; memset(buff,0,sizeof(buff)); if(NULL==(fstream=popen("ls -l","r"))) { fprintf(stderr,"execute command failed: %s",strerror(errno)); return -1; } if(NULL!=fgets(buff, sizeof(buff), fstream)) { printf("%s",buff); } else { pclose(fstream); return -1; } pclose(fstream); return 0; }
#include extern char **environ; int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]);
函數族的意義
#include int main(int argc, char *argv[]) { char *envp[]={"PATH=/tmp", "USER=lei", "STATUS=testing", NULL}; char *argv_execv[]={"echo", "excuted by execv", NULL}; char *argv_execvp[]={"echo", "executed by execvp", NULL}; char *argv_execve[]={"env", NULL}; if(fork()==0) { if(execl("/bin/echo", "echo", "executed by execl", NULL)<0) perror("Err on execl"); } if(fork()==0) { if(execlp("echo", "echo", "executed by execlp", NULL)<0) perror("Err on execlp"); } if(fork()==0) { if(execle("/usr/bin/env", "env", NULL, envp)<0) perror("Err on execle"); } if(fork()==0) { if(execv("/bin/echo", argv_execv)<0) perror("Err on execv"); } if(fork()==0) { if(execvp("echo", argv_execvp)<0) perror("Err on execvp"); } if(fork()==0) { if(execve("/usr/bin/env", argv_execve, envp)<0) perror("Err on execve"); } }