【问题标题】:Accessing exit codes from a c program从 c 程序访问退出代码
【发布时间】:2020-11-19 06:50:15
【问题描述】:

我试图在整个国际上找到解决方案,但论坛一直说这是不可能的,所以我在这里提出我的问题。 shell(任何 shell,如 bash)如何跟踪 exit codes。是通过跟踪他们的子进程吗? (如果是这样,我怎么能在我创建和杀死许多子进程的程序中实现这样的事情)或者是否有一个等效于$? 的全局变量,我可以在c 中访问?还是他们将其存储在文件中?

【问题讨论】:

    标签: c shell exit-code


    【解决方案1】:

    这是一个在不存在的路径上执行 grep 并在父级中获取返回码的示例:

    代码:

    #include <errno.h>
    #include <sys/wait.h>
    #include <stdio.h>
    #include <unistd.h>
    
    
    int main(int argc, char* argv[]) {
    
        pid_t childPid;
        switch(childPid = fork()) {
        case -1:
            fprintf(stderr, "Error forking");
            return 1;
        case 0:
            printf("CHILD: my pid is: %d\n", getpid());
            int ret = execlp(argv[1], argv[1], argv[2], argv[3], (char *) NULL);
            if (ret == -1) {
                printf("CHILD: execv returned: %d\n", errno);
                return errno;
            }
            break;
        default:
            printf("I am the parent with a child: %d\n", childPid);
            int childRet;
            wait(&childRet);
            printf("PARENT, child returned: %d\n", childRet >> 8);
        }
        return 0;
    }
     
    

    执行:

    # Example of Failure execution:
    
    [ttucker@zim c]$ cc -o stackoverflow so.c && ./stackoverflow grep test /does/not/exists
    I am the parent with a child: 166781
    CHILD: my pid is: 166781
    grep: /does/not/exists: No such file or directory
    PARENT, child returned: 2
    
    # Example of a successful execution:
    
    [ttucker@zim c]$ cc -o stackoverflow so.c && ./stackoverflow echo foo bar
    I am the parent with a child: 166809
    CHILD: my pid is: 166809
    foo bar
    PARENT, child returned: 0
    
    

    【讨论】:

    • 好的,所以根据您的回答,我假设外壳也知道当您执行echo "$?" 时该做什么,通过跟踪每个子项中每个命令的退出状态。
    • 是的,我相信是这样的。我认为在 Linux 和可能的其他操作系统中,当您创建一个进程时,您必须分叉当前进程并执行,如图所示。我认为 Bash(这被过度简化了)只是一个循环并等待用户输入的过程,然后是 fork()s 和 exec()s,同时跟踪一堆不同的东西,比如返回码。跨度>
    【解决方案2】:

    '等待'或'waitpid'。

    这样,您可以跟踪子进程以及它们是如何终止的。

    您可以使用宏“WEXITSTATUS”检查“wstatus”,它是“main”函数的返回值(如果以“exit”终止)。

    【讨论】:

    • WIFEXITED() 看看它是正常退出还是通过其他方式结束(WIFSIGNALED() 表示它是否因信号而死)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多