Почему дочерний процесс возвращает состояние выхода = 32512 в Unix? - PullRequest
12 голосов
/ 12 апреля 2011

В моей программе я выполняю данную команду и получаю результат (журнал и состояние выхода).Также моя программа должна поддерживать специфичные для оболочки команды (то есть команды, которые содержат специфические для оболочки символы ~ (tild), | (pipe), *).Но когда я пытаюсь запустить sh -c ls | wc в моем домашнем каталоге с помощью моей программы, это не удалось, и его состояние выхода было 32512, также в потоке stderr "sh: ls | wc: command not found" было напечатано.1005 * работает правильно, если я запускаю его в оболочке.

В чем проблема?Или, более предпочтительно, как я могу запускать специфичные для оболочки команды через мою программу (т.е. какую команду, с какими параметрами мне следует запускать)?

Ниже приведена часть кода после дочерней (fork).Он выполняет команду.

tokenized_command - это std::vector<std::string>, где в моем случае хранятся "sh", "-c", "ls", "|", "wc", также я пытался сохранить там "sh", "-c", "\"ls | wc\"", но результат тот же.command - это char *, где хранится полная командная строка.

        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);
        }

PS

Я знаю, что использование system(command) вместо execvp может решить мою проблему.Но system() ждет, пока команда не завершится, и этого недостаточно для моей программы.Также я уверен, что при реализации system() используется одна из функций семейства exec, поэтому проблему можно решить также с помощью exec, но я не знаю, как.

Ответы [ 2 ]

25 голосов
/ 12 апреля 2011

execvp принимает путь к исполняемому файлу и аргументы для запуска этого исполняемого файла.Он не принимает команды оболочки Bourne.

ls | wc - это команда оболочки Bourne (среди прочих), и ее нельзя разбить на путь к исполняемому файлу и некоторым аргументам из-за использованиятруба.Это означает, что он не может быть выполнен с использованием execvp.

Чтобы выполнить команду оболочки Bourne с использованием execvp, нужно выполнить 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 sh -c ls '|' wc.

И оба они сильно отличаются от команды оболочки 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, но такой программы нет.

0 голосов
/ 12 апреля 2011

Вы должны выполнить sh -c 'ls | wc'.

Опция -c ожидает команду в виде строки. Конечно, в оболочке это работает, потому что нет разницы между порождением ls и перенаправлением вывода на wc и запуском ls | wc в отдельной оболочке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...