В моей программе я выполняю заданную команду и получаю результат (журнал и статус выхода). Также моя программа должна поддерживать специальные команды оболочки (то есть команды, которые содержат специальные символы оболочки ~ (tild), | (pipe), *). Но когда я пытаюсь запустить sh -c ls | wc в своем домашнем каталоге через мою программу, он завершился неудачно, и его статус выхода был 32512, также был напечатан поток stderr "sh: ls | wc: command not found".
Но интересно то, что команда sh -c ls | wc работает корректно, если я запускаю ее в оболочке.
В чем проблема? Или более предпочтительным, как я могу запускать специальные команды с помощью моей программы (i.ec какая команда, с какими параметрами я должен работать)?
Ниже приведена часть кода в дочерней части после 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);
}
P.S.
Я знаю, что использование system(command) вместо execvp может решить мою проблему. Но system() ждет, пока команда не будет завершена, и это недостаточно для моей программы. И также я уверен, что в реализации system() используется одна из функций exec-family, поэтому проблема может быть решена и с помощью exec, но я не знаю, как это сделать.