如何使用C运行外部程序并传递命令行参数?如果必须使用操作系统API,请提供Windows,Mac和Linux的解决方案。
这真的取决于你想要做什么,因为它:
尽管如此,我会尝试为您提供一些信息来帮助您做出决定。
在UNIX上,fork()
会从调用fork的位置创建一个进程的克隆。也就是说,如果我有以下进程:
#include <unistd.h>
#include <stdio.h>
int main()
{
printf( "hi 2 u\n" );
int mypid = fork();
if( 0 == mypid )
printf( "lol child\n" );
else
printf( "lol parent\n" );
return( 0 );
}
输出将如下所示:
hi 2 u
笑死孩子
笑死父母
当你使用 fork()
函数时,子进程返回的进程ID为0,而父进程返回的进程ID是子进程的进程ID。注意,“hi2u”只会由父进程打印一次。
execve()
及其相关函数几乎总是和 fork()
一起使用。 execve()
和类似的函数将当前的栈帧覆盖为您传递给它的应用程序名称。 execve()
几乎总是与 fork()
一起使用,其中您会 fork 一个子进程,如果您是父进程,则继续进行必要的操作,如果您是子进程,则执行一个新进程。 execve()
通常也与 waitpid()
一起使用 -- waitpid 接收一个子进程的 PID,直到子进程终止并将子进程的退出状态返回给您。
有了这些信息,您应该能够编写一个非常基本的 shell;一个接受命令行上的进程名称并运行您告诉它运行的进程的 shell。当然,shell 做的不仅仅是这些,还有输入输出的管道等,但是您应该能够使用 fork()
、execve()
和 waitpid()
完成基本操作。
注意:此内容仅适用于*nix系统!在Windows上将无法使用。
希望这对您有所帮助。
如果你想执行更加复杂的操作,比如读取外部程序的输出,那么你可能更好地使用popen系统调用。例如,要以编程方式访问目录列表(这是一个有点愚蠢但作为例子很有用),可以编写以下内容:
#include <stdio.h>
int main()
{
int entry = 1;
char line[200];
FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
while ( fgets(line, 199, output) )
{
printf("%5d: %s", entry++, line);
}
}
生成这样的输出
1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...
!feof(output)
,则不要执行 pclose(output)
(参考自微软的示例)。返回 -1;否则执行 pclose(output)
并返回 0。 - 7vujy0f0hy#include <stdlib.h>
int main()
{
system("echo HAI");
return 0;
}
我要强烈警告大家,不要使用system,而且在编写库时100%永远不要使用system。它是30年前设计的,当时多线程还未被称为 Unix 这个玩具操作系统所知。即使今天几乎所有程序都支持多线程,它仍然不可用。
请使用popen或进行fork + execvp操作,其他方法会导致信号处理难以找到的问题、环境处理代码崩溃等问题。使用“system”纯粹是一种邪恶行为,最受欢迎和评价最高的答案竟然在推广使用“system”,这真是一种耻辱。在工作场所推广可卡因会更健康。
QString program = "./yourspawnedprogram";
QProcess * spawnedProcess = new QProcess(parent);
spawnedProcess->start(program);
// or spawnedProcess->startDetached(program);
此外,您甚至可以从母进程中杀死子进程,并通过流与其保持通信。
说到平台相关的编程技巧,在Windows上使用CreateProcess,在Posix(Linux、Mac)上使用fork
+execvp
。但是system()
应该可以满足您的基本需求,并且是标准库的一部分。