我想在C代码中执行另一个程序。 例如,我想执行一个命令如何在Linux中使用参数在C代码中执行外部程序?
./foo 1 2 3
foo
是存在于同一文件夹中的程序,并且是1 2 3
参数。 foo
程序创建一个文件,将在我的代码中使用。
我该怎么做?
我想在C代码中执行另一个程序。 例如,我想执行一个命令如何在Linux中使用参数在C代码中执行外部程序?
./foo 1 2 3
foo
是存在于同一文件夹中的程序,并且是1 2 3
参数。 foo
程序创建一个文件,将在我的代码中使用。
我该怎么做?
使用system()
:
int status = system("./foo 1 2 3");
system()
将等待FOO完成执行,然后返回,你可以用它来检查例如状态变量退出码。 man 2 wait
你的linux系统会列出你可以用它来检查状态的不同的宏上,最有趣的是WIFEXITED
和WEXITSTATUS
另外,如果你需要阅读Foo的输出到标准输出,使用popen()
。
system()声明在哪里? –
stdlib.h,在另一个答案中找到。 –
请参阅https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132以及本作者发布的替代答案。 –
在C
#include <stdlib.h>
system("./foo 1 2 3");
在C++
#include <cstdlib>
std::system("./foo 1 2 3");
然后,打开并读取该文件如常。
这个怎么样:
char* cmd = "./foo 1 2 3";
system(cmd);
将字符串文字赋值给char *时,它在C++中被弃用,在C中变成坏主意。 –
我的意思是:它是有效的,而不仅仅是“while”。 :) –
这里是延伸到可变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);
您可以使用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;
}
从子进程中使用execl或execv会更有效率,因为它不会使用shell,它不会分叉新线程,并且在您调用system之后即将退出。另外,如果你不叫wait(),这个过程将会变成僵尸。 – Billy
system
函数调用shell来运行该命令。虽然这很方便,但它已经众所周知security implications。如果您可以完全指定要执行的程序或脚本的路径,并且您可以承受失去的平台独立性,则可以使用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>
参见related SE post用于需要经由文件描述符如stdin
和stdout
执行的程序的通信状况。
所以上面的代码不使用shell来执行命令? – user3769778
#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;
}
这个问题为什么要求C代码,并用C++标记? – Johan