使用exec在新进程中执行系统命令

using exec to execute a system command in a new process

本文关键字:执行 系统命令 进程 exec 新进程 使用      更新时间:2023-10-16

我正在尝试生成一个执行系统命令的进程,而我自己的程序仍在继续,并且两个进程将并行运行。我在linux上工作。

我在网上查了一下,听起来我应该使用exec() family。但它并不像我期望的那样工作。例如,在下面的代码中,我只看到"before"被打印出来,而没有看到"done"。

我很好奇我是否错过了什么?

#include <unistd.h>
#include <iostream>
using namespace std;
main()
{
   cout << "before" << endl;
   execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);
   cout << "done" << endl;
}
(更新)

谢谢你的评论。现在我的程序是这样的。一切都很好,除了最后,我必须按回车键来完成程序。我不知道为什么我必须按最后一个回车键?

#include <unistd.h>
#include <iostream>
using namespace std;
main()
{
   cout << "before" << endl;
   int pid = fork();
   cout << pid << endl;
   if (pid==0) {
      execl("/bin/ls", "ls", "-r", "-t", "-l", (char *) 0);
   }
   cout << "done" << endl;
}

您错过了呼叫fork的电话。exec所做的只是用新程序的进程映像替换当前进程映像。使用fork生成当前进程的副本。它的返回值会告诉你正在运行的是子进程还是原始父进程。如果是孩子,呼叫exec


一旦你做了这个改变,只有出现,你需要按Enter键来完成程序。实际发生的情况是这样的:父进程派生并执行子进程。两个进程同时运行,两个进程同时打印到stdout。他们的输出是乱码的。父进程要做的事情比子进程少,因此它先终止。当它终止时,正在等待它的shell将醒来并打印常规提示符。同时,子进程仍在运行。它打印更多的文件条目。最后,它终止。shell没有注意到子进程(它的孙子进程),所以shell没有理由重新打印提示符。更仔细地查看您得到的输出,您应该能够在上面的ls输出中找到您通常使用的命令提示符。

光标显示等待您按下某个键。当您这样做时,shell打印一个提示符,一切看起来都很正常。但就蛋壳而言,一切都很正常。您之前可以键入另一个命令。它看起来可能有点奇怪,但shell会正常执行它,因为它只接收来自键盘的输入,而不是从子进程向屏幕打印额外字符的输入。

如果您在单独的控制台窗口中使用top之类的程序,您可以在按Enter之前观察并确认两个程序已经完成运行。

Exec函数族用新的可执行文件替换当前进程。

使用fork()函数之一,并让子进程exec处理新图像。

[响应更新]

它正在做你告诉它的事情:你不需要按"enter"键来完成程序:它已经退出了。shell已经给出了提示符:

[wally@zenetfedora ~]$ ./z
before
22397
done
[wally@zenetfedora ~]$ 0               << here is the prompt (as well as the pid)
total 5102364
drwxr-xr-x.  2 wally wally       4096 2011-01-31 16:22 Templates
...

ls的输出需要一段时间,所以它隐藏了提示符。如果您希望输出以更合乎逻辑的顺序显示,请在"done"之前添加sleep(1)(或更长)。

您错过了execl()用/bin/ls替换内存中的当前程序的部分

我建议看看popen(),它将分叉并执行一个新进程,然后让你通过管道读写它。(或者,如果你需要读写,fork()自己,然后exec())