c++ - 如何关闭先前打开的 shell (C++)

标签 c++ linux shell sh

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

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

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

最佳答案

当 script.sh 完成时,它运行的 shell 将自行终止,您不需要“关闭”它。

但是,如果父进程仍在运行,则子进程将成为“僵尸”(在 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 (例如从命令行中的“kill -9”):

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

关于c++ - 如何关闭先前打开的 shell (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29720482/

相关文章:

shell - 如何更改 shell/bash 中的列名?

c++ - 如何使用 C++ 制作测验数据库

linux - 在下一行的空白区域下方重复第一行中第一列的值

c++ - 在哪里声明这个记录器对象?

linux - 如果 Perl 尝试对正在上传的文件调用 move() 会发生什么?

c++ - 请解释此链接错误 : referenced in section . rodata

python - 如何在 Python 中正确地将双引号传递给 awk 子进程?

windows - 转换 : GIT SHELL to GIT BATCH script

c++ - 容器中需要显式移动构造函数吗?

c++ - 如何将 vector<string> 的元素复制到字符串中?