为什么子进程在unix中返回退出状态= 32512?

Mih*_*yan 13 c c++ unix shell posix

在我的程序中,我正在执行给定的命令并获得结果(日志和退出状态).此外,我的程序必须支持特定于shell的命令(即包含shell特定字符〜(tild),|(管道),*)的命令.但是当我尝试sh -c ls | wc通过我的程序在我的主目录中运行它失败并且它的退出状态是32512时,也"sh: ls | wc: command not found"打印了stderr流.

但有趣的是,sh -c ls | wc如果我在shell中运行它,该命令的工作正常.

问题是什么?或者更优选的是如何通过我的程序运行shell特定命令(即哪个命令应该运行哪些参数)?

下面的代码部分是在fork()之后的子部分.它执行命令.

tokenized_commandstd::vector<std::string>在我的情况下"sh", "-c", "ls", "|", "wc"存储,也是我试图存储在那里"sh", "-c", "\"ls | wc\"",但结果是一样的.commandchar *完整的命令行的存储位置.

        boost::shared_array<const char *> bargv(new const char *[tokenized_command.size() + 1]);
        const char **argv = bargv.get();
        for(int i = 0; i < tokenized_command.size(); ++i)
        {
            argv[i] = tokenized_command[i].c_str();
            printf("argv[%d]: %s\n", i, argv[i]); //trace
        }
        argv[tokenized_command.size()] = NULL;

        if(execvp(argv[0], (char * const *)argv) == -1)
        {
            fprintf(stderr, "Failed to execute command %s: %s", command, strerror(errno));
            _exit(EXIT_FAILURE);
        }
Run Code Online (Sandbox Code Playgroud)

PS

我知道使用system(command)相反execvp可以解决我的问题.但system()等到命令完成,这对我的程序来说还不够好.并且我确信在system()使用exec-family函数之一时,也可以解决问题exec,但我不知道如何解决.

ike*_*ami 26

execvp获取可执行文件的路径,以及用于启动该可执行文件的参数.它不需要bourne shell命令.

ls | wc是一个bourne shell命令(以及其他命令),由于使用了管道,它不能分解为可执行文件的路径和一些参数.这意味着它无法使用execvp.

要使用bourne shell命令execvp,必须执行sh并传递-c参数命令.

所以你想要执行ls | wc使用execvp.

char *const argv[] = {
    "sh",
    "-c", "ls | wc",  // Command to execute.
    NULL
};

execvp(argv[0], argv)
Run Code Online (Sandbox Code Playgroud)

你显然试过了

char *const argv[] = {
    "sh",
    "-c", "ls",  // Command to execute.
    "|",         // Stored in called sh's $0.
    "wc",        // Stored in called sh's $1.
    NULL
};
Run Code Online (Sandbox Code Playgroud)

这与bourne shell命令相同sh -c ls '|' wc.

两者都与shell命令非常不同sh -c ls | wc.那就是

char *const argv[] = {
    "sh",
    "-c", "sh -c ls | wc",  // Command to execute.
    NULL
};
Run Code Online (Sandbox Code Playgroud)

你似乎在思考|wc传递给了sh,但事实并非如此.|是一个特殊字符,它导致管道,而不是参数.


至于退出代码,

Bits 15-8 = Exit code.
Bit     7 = 1 if a core dump was produced.
Bits  6-0 = Signal number that killed the process.
Run Code Online (Sandbox Code Playgroud)

32512 = 0x7F00

所以它没有死于信号,没有产生核心转储,它退出代码127(0x7F).

什么127意味着不清楚,这就是为什么它应该伴随着错误信息.你试图执行程序ls | wc,但没有这样的程序.