【问题标题】:How to create a program that reads the last commands exit status?如何创建一个读取最后一个命令退出状态的程序?
【发布时间】:2014-07-31 20:41:22
【问题描述】:

在 Linux C 中,如何读取最后一个程序的退出状态。

例如:

true; echo $?

将显示 0 表示成功。但我想用 C 程序替换它:

true; ./echo_exit_status

最后一个退出代码 $ 如何/在哪里?可用于 C 程序?

【问题讨论】:

  • 我认为你不能(除非将其提供给 C 程序)。
  • 该信息存储在 shell 进程中。 C 程序(即使它是 shell 的子进程)无法访问它。
  • 我以为肯汤普森是这么说的
  • @Jack 你建议怎么做?通过入侵 shell 自己的内存?
  • @Jack, PATH 是一个环境变量(适用于所有程序),而不是一个shell变量(仅适用于shell) ;相比之下,$? 不仅仅是一个常规的 shell 变量(您可以使用 export 将其暴露给环境,从而暴露给子进程),而是一个具有自身扩展行为的特殊参数,并且不能在全部。

标签: c linux shell exit-code


【解决方案1】:

最后一个命令的退出状态可供后续执行的程序访问(不存在极其可怕的骇客——使用调试器或类似工具附加到父 shell)。

您可以编写一个 shell 函数或帮助程序,将这个值导出到环境中——但没有任何解决方案不需要 shell 参与。

【讨论】:

    【解决方案2】:

    您必须知道 pid,否则它是 http://linux.die.net/man/2/waitpid 来自手册页的更多信息

       WIFEXITED(status)
              returns true if the child terminated normally, that is, by
              calling exit(3) or _exit(2), or by returning from main().
    
       WEXITSTATUS(status)
              returns the exit status of the child.  This consists of the
              least significant 8 bits of the status argument that the child
              specified in a call to exit(3) or _exit(2) or as the argument
              for a return statement in main().  This macro should be
              employed only if WIFEXITED returned true.
    

    这是一个例子

       #include <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>
    
       int
       main(int argc, char *argv[])
       {
           pid_t cpid, w;
           int status;
    
           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }
    
           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));
    
           } else {                    /* Code executed by parent */
               do {
                   w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }
    
                   if (WIFEXITED(status)) {
                       printf("exited, status=%d\n", WEXITSTATUS(status)); //this line will return the exit status, whether it was 1 or 0
                   } else if (WIFSIGNALED(status)) {
                       printf("killed by signal %d\n", WTERMSIG(status));
                   } else if (WIFSTOPPED(status)) {
                       printf("stopped by signal %d\n", WSTOPSIG(status));
                   } else if (WIFCONTINUED(status)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(status) && !WIFSIGNALED(status));
               exit(EXIT_SUCCESS);
           }
       }
    

    【讨论】:

    • 这如何帮助获取 shell 执行的最后一个命令的返回状态码?运行 C 程序时,该命令的进程不再存在。
    • 这行不通,除非 shell 不等待它的孩子(而且你没有僵尸,因为你的 shell 等待它的孩子)。
    • 仔细阅读问题。
    • @Sevki,即使您已编辑此内容以更详尽地演示 waitpid() 的使用,但这并不会改变 waitpid() 不适用于已经具有退出状态的程序在程序启动之前从进程表中删除(由父 shell 本身调用wait())。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2017-11-11
    相关资源
    最近更新 更多