Используйте соответствующие системные вызовы напрямую : pipe (2) , fork (2) , dup2 (2) , закрыть (2) , execve (2) , waitpid (2) . Прочитайте хорошую книгу по программированию для Linux (возможно, старую ALP , в которой есть несколько глав, связанных с вашим вопросом). Ищите вдохновение в исходном коде других бесплатных программ, работающих с конвейерами (например, какой-нибудь простой оболочки, такой как sash
) и / или в вашем libc
(или musl-libc , он очень читабелен код) для кода popen
.
У нас нет места и времени для подробного объяснения, но вы найдете много ресурсов в Интернете, и ALP можно загрузить бесплатно; конечно execve
- это последний системный вызов, который обычно выполняется в дочернем процессе, поскольку он повторно инициализирует виртуальное адресное пространство.
Для чтения с канала без ограничения длины строки. Либо используйте read (2) вручную (и позаботьтесь о буферизации), либо рассмотрите getline (3) (см. Также f dopen (3) )
Вас могут заинтересовать такие фреймворки, как POCO или Qt .
Вы, вероятно, хотите избежать popen (3) (и вам не нужно что-то, используя /bin/sh
, если только ваша команда не нуждается в расширении для globbing ; см. Глоб (7) ). * +1048 *
Помните о сигнале (7) и о безопасности сигнала (7) (и, возможно, опрос (2) ...)
Программа, которую я хочу запустить в своем приложении c ++, это просто ps aux
Тогда вам, вероятно, следует не запускать какой-либо внешний процесс, а вместо этого обращаться /proc/
напрямую (см. proc (5) ; вам понадобится opendir (3) , readdir (3) и т. д ...) или, возможно, через libproc
. Конечно, ps aux
обращается к самому /proc/
(поэтому вы не получите ничего, кроме некоторой простоты, запустив ps
, и потеряете некоторую производительность и некоторую надежность при его использовании). См. Также это , это , это , это , это ответы.
В комментарии вы упоминаете
Мне нужно знать, запущены ли некоторые процессы, учитывая как его имя, так и аргументы.
Это хороший случай для программного доступа к /proc/
: цикл в каталоге /proc/
с opendir
, цикл readdir
, enddir
. Для каждой записи, заданной readdir
, убедитесь, что она имеет числовое имя (начиная с цифры), в противном случае пропустите ее. С этим числовым именем (например, 1234
) создайте путь, подобный /proc/1234/cmdline
и , откройте его, затем проанализируйте его содержимое (у него есть разделяющие NUL байты). Это, вероятно, не сложнее, чем запуск процесса ps aux
, получение и анализ его выходных данных, и, безусловно, более эффективный. (Чтобы разобраться в деталях, запустите od -cx /proc/self/cmdline
, затем od -cx /proc/$(pidof systemd-journald)/cmdline
и поймите его вывод).