Я написал дочерний код выполнения команды для Win32, используя CreateProcess:
CreateProcessW(NULL, // app
&commandW[0], // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&startup_info, // STARTUPINFOW pointer
&process_info); // receives PROCESS_INFORMATION
Это использует «хитрость» и помещает всю команду во второй аргумент, который обычно содержит только те аргументы, которые передаются программе. Я хочу сделать то же самое для POSIX, но тот же «трюк» не работает с execlp
функция (и я ставлю все остальные). Есть ли способ по-прежнему использовать один std::string command
и начать процесс? Разделение команды на исполняемое имя файла и аргументы были бы возможны, но я бы хотел избежать большой работы, если это возможно.
Вы можете вызвать оболочку, передать большую строку в оболочку и позволить оболочке разобраться с ней. Попробуй сам:
sh -c "echo 'hello world'"
(то есть передать два аргумента «-c
«и большая строка, содержащая команду и аргументы)
Еще лучше: сделайте первую команду exec
, который заставит ваш новый процесс «заменить» созданную им оболочку, тогда никто даже не узнает, что он был запущен с использованием оболочки.
Как отмечено в комментариях @ecatmur, это точная функциональность system
вызов.
Но вы открываете себя для потенциальных (серьезных) проблем: теперь вам приходится иметь дело с цитированием и экранированием символов. Оболочка может (и будет) интерпретировать любые специальные символы, если они не экранированы, и любые аргументы, которые имеют пробелы, должны быть правильно указаны в кавычках.
Есть причина, по которой Unix-подобные операционные системы обрабатывают аргументы так, как они это делают.
Мое мнение таково, что метод Windows в корне ошибочен. Это серьезный недосмотр дизайна, который не позволяет передавать сложные строки в качестве аргументов командной строки другим программам.
Других решений пока нет …