popen создает дополнительный процесс sh

Я пытаюсь выполнить (разветвить) команду с помощью popen, и я вижу, что там также есть лишний sh -c "my_command process".

Я хочу свести к минимуму количество процессов, так можно ли от этого избавиться?

пс вывод:

root@home% ps awux | grep my_command
root 638  0.0  0.1  040  1424  ??  I    10:12PM   0:00.00 sh -c my_command /home/war
root 639  0.0  0.0  608   932  ??  S    10:12PM   0:00.01 my_command /home/war

Прочитав man-страницу, я знаю, как работает popen().

Ответ на проблему выше был предоставлен @R..

Мое требование таково: мне нужно сбросить вывод команды в файл, прочитать этот файл построчно и обработать вывод. Вот почему я использую popen, потому что он возвращает вывод в файл. Могу ли я добиться этого с помощью любого вызова exec?


person hari    schedule 19.07.2011    source источник
comment
Покажите нам соответствующую часть вашего кода.   -  person NPE    schedule 19.07.2011
comment
Если это то, как должен работать popen(), то какая другая альтернатива для меня?   -  person hari    schedule 19.07.2011
comment
@aix: почему? Я считаю, что этот вопрос самодостаточен. Не так ли?   -  person hari    schedule 19.07.2011
comment
@hari: Если - почти 7 лет спустя - вы все еще заинтересованы в том, почему используется дополнительный процесс sh (как вы указали в комментариях ниже), я спросил конкретный вопрос по этому поводу.   -  person domsson    schedule 20.02.2018


Ответы (3)


Вы должны слушать хороших людей, которые советуют вам не использовать popen - это плохо. Но есть простое решение проблемы, с которой вы столкнулись — добавьте exec в начало командной строки, которую вы передаете popen. То есть вместо:

popen("my_command /home/war", ...

использовать:

popen("exec my_command /home/war", ...
person R.. GitHub STOP HELPING ICE    schedule 19.07.2011
comment
Спасибо. Я обязательно слушаю всех. Я просто пытаюсь понять, почему это плохо. Если это плохо, почему это спроектировано/реализовано/стандартизировано/используется таким образом. Опять же, за мое образование :) Большое спасибо. - person hari; 19.07.2011
comment
Это плохо, потому что .. (1) вызов внешних программ через оболочку вводит уязвимости мета-символов оболочки, если вы не будете осторожны с кавычками, (2) popen допускает только одностороннюю связь, а не двустороннюю, и (3) вы у вас нет доступа к pid дочернего процесса, поэтому возникают проблемы, если вы хотите wait для других созданных вами дочерних процессов. Возможно и другие проблемы... - person R.. GitHub STOP HELPING ICE; 19.07.2011
comment
Согласитесь с (1) и (3). Как открывается односторонняя связь? благодаря. - person hari; 19.07.2011
comment
@hari Большинство реализаций допускают только popen("...", "r") или popen("...", "w"). То есть вы можете только писать или читать. В виде исключения BSD допускает r+. - person cnicutar; 19.07.2011

popen использует sh для порождения дочернего процесса, как system в системах POSIX.

Если вы хотите избежать этого, просто используйте fork, close, mkpipe и exec (что более или менее то, что popen делает внутри). Если вам не нужна труба, вы можете просто fork и exec.

person Matteo Italia    schedule 19.07.2011
comment
Спасибо за ответ. Для моего образования, почему popen это делает? если его можно избежать. Зачем создавать лишний процесс? - person hari; 19.07.2011
comment
Использование оболочки в качестве промежуточного шага позволяет коду использовать встроенные функции/возможности оболочки. Я не вижу других преимуществ, кроме этого. Тем не менее, как объяснено, вы можете легко избежать этого, используя системные вызовы. - person Matteo Italia; 19.07.2011
comment
Предположим, что команда была сценарием оболочки. Даже если был установлен бит выполнения, вам все равно нужно передать это через sh или bash (запуск exec в сценарии оболочки не работает). Следовательно, поскольку нет требования, чтобы любая программа была реализована как программа на языке C, возможно, вы захотите использовать сценарий оболочки, а проще просто пройти через оболочку. (эти другие сценарии, такие как python и perl, разрешаются оболочкой при анализе строки shebang, поэтому другие сценарии также поддерживаются) - person Foo Bah; 19.07.2011
comment
@Foo Bah: на самом деле IIRC нотация shebang обрабатывается непосредственно exec, для этого не требуется оболочка. Кроме того (опять же, IIRC), когда вы запускаете сценарий оболочки из оболочки, процесс оболочки не используется повторно, а запускается другой (если вы не используете команду . ). - person Matteo Italia; 19.07.2011
comment
Я опаздываю на вечеринку, но я склонен согласиться с @MatteoItalia: по крайней мере, справочная страница для execve явно указывает: execve() выполняет программу, на которую указывает имя файла. имя файла должно быть либо двоичным исполняемым файлом, либо сценарием, начинающимся со строки вида: #! interpreter [optional-arg] — что также должно быть верным для execvp, поскольку его справочная страница ссылается на страницу execve — не уверен насчет других функций семья. - person domsson; 20.02.2018

Что касается popen, предполагается, что он вызывает оболочку (прочитайте справочную страницу)

Чтобы пропустить процесс оболочки, вы можете выполнить fork/exec

person Foo Bah    schedule 19.07.2011