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

时间:2011-04-12 16:09:53

标签: c++ c shell unix posix

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

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

有什么问题?或者更可取的是如何通过我的程序运行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);
        }

P.S。

我知道使用system(command)代替execvp可以解决我的问题。但system()等待命令完成,这对我的程序来说还不够好。而且我确信在system()的实现中使用了一个exec-family函数,因此问题也可以通过exec来解决,但我不知道如何。

2 个答案:

答案 0 :(得分:24)

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

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

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

因此,您希望使用ls | wc执行execvp

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

execvp(argv[0], argv)

你显然已经尝试了

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

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

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

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

您似乎认为|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.

32512 = 0x7F00

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

127意味着什么不清楚,这就是它应该伴随错误信息的原因。您尝试执行程序ls | wc,但没有此类程序。

答案 1 :(得分:0)

您应该执行sh -c 'ls | wc'

选项-c需要一个字符串形式的命令。在shell中当然是有效的,因为产生ls和将输出重定向到wc并在单独的shell中启动ls | wc之间没有区别。