Когда вы выполняете команду:
ps -ef | grep cron
оболочка, которую вы используете
(... Я предполагаю, что в вашем случае bash, из-за атрибута цвета grep я думаю, что вы используете систему gnu, такую как дистрибутив Linux, но то же самое и в других unix/оболочках...)
выполнит вызов pipe()
для создания FIFO, затем fork()
(создаст свою текущую копию). Это создаст новый дочерний процесс. Этот новый сгенерированный дочерний процесс будет close()
использовать свой стандартный дескриптор выходного файла (fd 1) и присоединит fd 1 к стороне записи канала, созданного родительским процессом (оболочкой, в которой вы выполнили команду). Это возможно, потому что системный вызов fork()
будет поддерживать для каждого допустимый дескриптор открытого файла (в данном случае канал fd). После этого это будет exec()
первая (в вашем случае) ps
команда, найденная в вашей переменной окружения PATH
. С вызовом exec()
процесс станет командой, которую вы выполнили.
Итак, теперь у вас есть процесс оболочки с дочерним элементом, который в вашем случае является командой ps
с атрибутами -ef
.
В этот момент родитель (оболочка) снова fork()
s. Этот недавно сгенерированный дочерний процесс close()
s использует свой стандартный дескриптор входного файла (fd 0) и прикрепляет fd 0 к стороне чтения канала, созданного родительским процессом (оболочкой, в которой вы выполнили команду).
После этого будет exec()
первая (в вашем случае) grep
команда, найденная в вашей переменной окружения PATH.
Теперь у вас есть процесс оболочки с двумя дочерними процессами (родственными), где первый — это команда ps
с атрибутами -ef
, а второй — команда grep
с атрибутом cron
. Сторона чтения канала подключена к STDIN
команды grep
, а сторона записи подключена к STDOUT
команды ps
: стандартный вывод команды ps
подключен к стандартному вводу команды grep
.
Поскольку ps
написан для отправки на стандартный вывод информации о каждом запущенном процессе, а grep написан для получения на стандартный ввод чего-то, что должно соответствовать заданному шаблону, вы получите ответ на свой первый вопрос:
- оболочка работает:
ps -ef;
- оболочка работает:
grep cron;
ps
отправляет данные (даже содержащие строку "grep cron") на grep
grep
соответствует своему шаблону поиска из STDIN
и соответствует строке "grep cron" из-за атрибута "cron", который вы передали в grep
: вы указываете grep
сопоставлять строку "cron", и это происходит, потому что "grep cron" строка, возвращаемая ps
в момент начала выполнения grep
.
Когда вы выполняете:
ps -ef | grep '[c]ron'
переданный атрибут указывает grep
сопоставить что-то, содержащее «c», за которым следует «ron». Как и в первом примере, но в этом случае он нарушит строку соответствия, возвращаемую ps
, потому что:
- оболочка работает:
ps -ef;
- оболочка работает:
grep [c]ron;
ps
отправляет данные (даже содержащие строку grep [c]ron
) на grep
grep
не соответствует шаблону поиска из стандартного ввода, потому что строка, содержащая «c», за которой следует «ron», не найдена, но найдена строка, содержащая «c», за которой следует «]ron».
GNU grep
не имеет ограничения на соответствие строк, а на некоторых платформах (я думаю, Solaris, HPUX, aix) ограничение на количество строк задается переменной "$COLUMN" или шириной экрана терминала.
Надеемся, что этот длинный ответ немного прояснит процесс оболочки.
НАКОНЕЧНИК:
ps -ef | grep cron | grep -v grep
person
dAm2K
schedule
14.03.2012
sleep 3 | sleep 3 | sleep 3
;-) - person Alfe   schedule 17.09.2015