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

时间:2011-04-12 06:32:06

标签: c++ linux process parallel-processing exec

我正在尝试生成一个执行系统命令的进程,而我自己的程序仍在进行,两个进程将并行运行。我正在研究linux。

我在网上查了一下,听起来我应该使用exec()系列。但它并不像我预期的那样有效。例如,在下面的代码中,我只看到“之前”打印,但不是“完成”。

我很好奇,如果我发布任何东西?

#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;
}

[UPDATE]

感谢你们的评论。现在我的程序看起来像这样。一切正常,除了最后,我必须按回车完成程序。我不知道为什么我要按最后一次输入?

#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;
}

3 个答案:

答案 0 :(得分:18)

您错过了对fork的来电。所有exec所做的是将当前过程映像替换为新程序的映像。使用fork生成当前进程的副本。它的返回值将告诉您它是孩子还是正在运行的原始父母。如果是孩子,请致电exec


完成更改后,只有出现,您需要按Enter键才能完成程序。实际发生的是:父进程分叉并执行子进程。两个进程都运行,并且两个进程同时打印到stdout。他们的输出是乱码。父进程比子进程少,所以它首先终止。当它终止时,正在等待它的shell唤醒并打印通常的提示。同时,子进程仍在运行。它会打印更多文件条目。最后,它终止了。 shell没有注意子进程(它的孙子),所以shell没有理由重新打印提示。仔细查看你得到的输出,你应该能够找到埋在上面ls输出中的常用命令提示符。

光标出现,等待您按一个键。当你这样做时,shell会打印一个提示,所有看起来都很正常。但就外壳而言,一切都已经正常了。您之前可以输入另一个命令。它看起来有点奇怪,但shell会正常执行它,因为它只接收来自键盘的输入,而不是来自子进程将其他字符打印到屏幕上。

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

答案 1 :(得分:7)

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

要执行您需要的操作,请使用其中一个fork()函数,并让子进程exec成为新图像。

[对更新的回应]

这正是你所说的:你不必按“回车”来完成程序:它已经退出了。 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的输出需要一段时间,因此它会隐藏提示。如果您希望输出以更合理的顺序显示,请在“完成”之前添加sleep(1)(或者更长)。

答案 2 :(得分:2)

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

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