execl如何处理Linux中的“/ bin / sh”?

时间:2017-09-06 08:00:35

标签: linux bash shell system-calls execl

我阅读了APUE 3rd,8.13,系统函数,我看到了一个没有信号处理的系统函数实现版本。代码如下:

#include    <sys/wait.h>
#include    <errno.h>
#include    <unistd.h>

int system(const char *cmdstring)    /* version without signal handling */
{
    pid_t    pid;
    int        status;

    if (cmdstring == NULL)
        return(1);        /* always a command processor with UNIX */

    if ((pid = fork()) < 0) {
        status = -1;    /* probably out of processes */
    } else if (pid == 0) {                /* child */
        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127);        /* execl error */
    } else {                            /* parent */
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1; /* error other than EINTR from waitpid() */
                break;
            }
        }
    }

    return(status);
}

用于测试此版本系统功能的代码如下:

int main(void)
{
    int        status;

    if ((status = system("date")) < 0)
        err_sys("system() error");

    pr_exit(status);

    if ((status = system("nosuchcommand")) < 0)
        err_sys("system() error");

    pr_exit(status);

    if ((status = system("who; exit 44")) < 0)
        err_sys("system() error");

    pr_exit(status);

    exit(0);
}

测试代码的结果如图所示(如果您无法理解,只需忽略结果中的中文): test code result 我想知道为什么execl会返回,如果对/ bin / sh无效的“nosuchcommand”给/ bin / sh。在我看来,execl只是替换当前进程的代码然后从入口点运行,即使“nosuchcommand”对于/ bin / sh无效,它与execl无关,但与/ bin / sh无关。那么,execl如何知道“nosuchcommand”对/ bin / sh执行和返回无效? execl是否通过在执行/ bin / sh之前检查给/ bin / sh的命令来区别对待/ bin / sh,以便它知道提前给/ bin / sh的无效参数?我知道execl不会以不同方式处理/ bin / sh,那么,execl如何知道“nosuchcommand”对/ bin / sh执行和返回无效?

2 个答案:

答案 0 :(得分:1)

sh -c nosuchcommand本身会返回127.这是其中一个return codes with a special meaning

所以我认为你并没有看到execl在这种情况下实际返回。

答案 1 :(得分:1)

它不“知道”。它只是执行你告诉它的内容。 /bin/sh然后报告无法找到它,之后/bin/sh退出非零退出代码,在这种情况下为127

另请注意,您不能完全依赖它127,因为它是特定于shell的。某些shell(包括某些操作系统上的/bin/sh)将返回1