如何关闭以前打开的shell(C ++)

时间:2015-04-18 17:24:45

标签: c++ linux shell sh

我在我的C ++代码中打开这样的shell:

int pid = fork()
if (pid==0){
    system("script.sh")
}
[rest of the code]

在我的C ++程序结束时,我还想关闭那个打开的shell,这可能吗?

1 个答案:

答案 0 :(得分:0)

当script.sh完成时,它运行的shell将自行终止,你不需要"关闭"它

但是,如果父进程仍在运行,则该子进程将成为" zombie" (在ps命令的输出中标有Z)。它将保持此状态,直到父级读取其返回代码或退出自身。

因此,如果[代码的其余部分]是简短的,您可能不需要做任何事情。当父母退出时,孩子将被操作系统清理。

但如果[代码的其余部分]运行了一段时间,或者多次调用此代码段,那么您需要清理僵尸,以免它们累积。这是通过waitpid()系统调用完成的。

例如:

int pid = fork()
if (pid==0){
    system("script.sh")
} else {
    int status = 0;
    int result = waitpid(pid, &status, 0);
    if (result == -1) {
        /* error */
    else {
       [rest of the code]
    }
}

请注意,父进程将在waitpid()调用中阻塞,直到子进程完成。如果这不是您想要的,您可以传递WNOHANG选项代替0作为最终参数。当它确实返回时,状态为'将包含脚本的返回码。您可以通过阅读" man 2 waitpid"。

来获得有关它的更多详细信息

更新(以回应脚本未自行退出的评论):

抽象中最干净的解决方案可能是重新设计,以便脚本自行退出,但如果由于某种原因不可能,则父进程可以强制使用kill()系统调用来终止脚本。代码看起来像这样:

#include <sys/types.h>
#include <signal.h>

int pid = fork()
if (pid==0){
    system("script.sh")
} else if (pid > 0) {
    /* do whatever in parent*/

    /* Note it is very important to check that fork did not fail */
    /* and return -1, because if you do "kill(-1, SIGTERM)" you */
    /* are in fact sending the TERM signal to **every process** */
    /* on your system. If running as root, this would be A Very Bad */
    /* Thing.  */
    kill(pid, SIGTERM);
} else {
    /* error */
}

kill()可以在出错时返回-1,所以如果你非常关心脚本没有被清理,你可以检查一下。例如,如果SIGTERM没有杀死它,你可以升级为发送SIGKILL(例如&#34; kill -9&#34;来自命令行):

if (kill(pid, SIGTERM) == -1) {
    kill(pid, SIGKILL);
}