如何在Linux中的C代码执行外部程序与参数?

我想在C代码中执行另一个程序。 例如,我想执行一个命令

./foo 1 2 3 

foo是存在于同一文件夹中的程序, 1 2 3是参数。 foo程序创build一个将在我的代码中使用的文件。

我该怎么做呢?

Solutions Collecting From Web of "如何在Linux中的C代码执行外部程序与参数?"

使用system()

 int status = system("./foo 1 2 3"); 

system()将等待foo完成执行,然后返回一个状态变量,您可以使用它来检查exitcode。 man 2 wait在你的linux系统上man 2 wait会列出你可以用来检查状态的各种宏,最有趣的将是WIFEXITEDWEXITSTATUS

或者,如果您需要读取foo的输出到stdout,请使用popen()

system函数调用一个shell来运行该命令。 虽然这很方便,但它具有众所周知的安全隐患 。 如果您可以完全指定要执行的程序或脚本的路径,并且您可以承受失去system提供的平台独立性,那么您可以使用execve包装器(如下面的exec_prog函数所示)来更安全地执行您的程序。

以下是您在调用者中指定参数的方法:

 const char *my_argv[64] = {"/foo/bar/baz" , "-foo" , "-bar" , NULL}; 

然后像这样调用exec_prog函数:

 int rc = exec_prog(my_argv); 

这是exec_prog函数:

 static int exec_prog(const char **argv) { pid_t my_pid; int status, timeout /* unused ifdef WAIT_FOR_COMPLETION */; if (0 == (my_pid = fork())) { if (-1 == execve(argv[0], (char **)argv , NULL)) { perror("child process execve failed [%m]"); return -1; } } #ifdef WAIT_FOR_COMPLETION timeout = 1000; while (0 == waitpid(my_pid , &status , WNOHANG)) { if ( --timeout < 0 ) { perror("timeout"); return -1; } sleep(1); } printf("%s WEXITSTATUS %d WIFEXITED %d [status %d]\n", argv[0], WEXITSTATUS(status), WIFEXITED(status), status); if (1 != WIFEXITED(status) || 0 != WEXITSTATUS(status)) { perror("%s failed, halt system"); return -1; } #endif return 0; } 

记住包括:

 #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> 

查看相关的SE帖子 ,了解需要通过文件描述符(如stdinstdout与执行的程序进行通信的情况。

你可以使用fork()system()这样你的程序不必等到system()返回。

 #include <stdio.h> #include <stdlib.h> int main(int argc,char* argv[]){ int status; // By calling fork(), a child process will be created as a exact duplicate of the calling process. // Search for fork() (maybe "man fork" on Linux) for more information. if(fork() == 0){ // Child process will return 0 from fork() printf("I'm the child process.\n"); status = system("my_app"); exit(0); }else{ // Parent process will return a non-zero value from fork() printf("I'm the parent.\n"); } printf("This is my main program and it will continue running and doing anything i want to...\n"); return 0; } 

在C

 #include <stdlib.h> system("./foo 1 2 3"); 

在C ++中

 #include <cstdlib> std::system("./foo 1 2 3"); 

然后像往常一样打开并阅读文件。

 #include <unistd.h> int main() { if (fork() == 0) { execl("foo", "foo", "1", "2", "3", 0); # We woundn't still be here if execl() was successful, so we exit with a non-zero value. return -1; } return 0; } 

这样怎么样:

 char* cmd = "./foo 1 2 3"; system(cmd); 

当你没有args硬编码时(虽然在这个例子中它们在技术上仍然是硬编码的,但是应该很容易找出如何扩展…),这里是扩展到变量args的方法:

 #include <stdio.h> #include <stdlib.h> #include <string.h> int argcount = 3; const char* args[] = {"1", "2", "3"}; const char* binary_name = "mybinaryname"; char myoutput_array[5000]; sprintf(myoutput_array, "%s", binary_name); for(int i = 0; i < argcount; ++i) { strcat(myoutput_array, " "); strcat(myoutput_array, args[i]); } system(myoutput_array);