В моей программе я выполняю заданную команду и получаю результат (журнал и статус выхода). Также моя программа должна поддерживать специальные команды оболочки (то есть команды, которые содержат специальные символы оболочки ~ (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
, но я не знаю, как это сделать.