2011-04-12 122 views
15

我试图产生一个执行系统命令的进程,而我自己的程序仍在继续,两个进程将并行运行。我正在linux上工作。使用exec在新进程中执行系统命令

我在网上查找,听起来像我应该使用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; 
} 

[更新]

谢谢你的人的意见。现在我的程序看起来像这样。一切工作正常,除了最后,我不得不按下完成程序。我不知道为什么我必须按最后输入?

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

你的主要应该是'INT main',并在结束时,你应该添加一个'返回0;' 你有它的方式,很可能你的编译器将填补最后,并会在最后加上“按任意按钮继续” – akaltar 2012-08-10 21:17:14

回答

14

您错过了对fork的呼叫。所有exec确实是用替换当前过程映像与新程序的。使用fork生成当前进程的副本。它的返回值会告诉你它是否是孩子或正在运行的原始父代。如果是孩子,请致电exec


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

光标出现等待您按下某个键。当你这样做的时候,shell会打印一个提示符,而且看起来都很正常。但就壳而言,一切都已经很正常。你以前可以输入另一个命令。这看起来有点奇怪,但shell通常会执行它,因为它只接收来自键盘的输入,而不是从子进程向打印机添加其他字符。

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

7

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

要做你所需要的,使用fork()函数之一,并让子进程exec新的图像。

[响应更新]

这是做什么你告诉它:你不必按“Enter”完成程序:它已经退出。外壳已经给出提示:

[[email protected] ~]$ ./z 
before 
22397 
done 
[[email protected] ~]$ 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)(或者更长)。

+1

应该为孩子添加一个“等待”,而不是“睡眠” – Hasturkun 2011-04-13 08:25:22

2

你错过了其中EXECL()在内存中/bin/ls

替换您当前程序中的一部分,我会建议看popen()将叉和exec一个新的进程,然后让你读或写通过它管道。 (或者,如果你需要读取和写入,fork()自己,那么exec()