При выполнении команды:
ps -ef | grep cron
оболочка, которую вы используете
(... я предполагаю, что bash в вашем случае из-за атрибута цвета grep, я думаю, что вы работаете с системой GNU, такой как дистрибутив linux, но то же самое относится и к другим unix / shell ...)
выполнит вызов pipe()
, чтобы создать FIFO, затем он fork()
(создаст рабочую копию самого себя). Это создаст новый дочерний процесс. Этот новый сгенерированный дочерний процесс close()
будет использовать стандартный дескриптор выходного файла (fd 1) и присоединит fd 1 к стороне записи канала, созданного родительским процессом (оболочкой, в которой вы выполнили команду). Это возможно, потому что системный вызов fork()
будет поддерживать для каждого действительный дескриптор открытого файла (в данном случае это канал fd). После этого будет exec()
первая (в вашем случае) команда ps
, найденная в вашей переменной окружения PATH
. При вызове exec()
процесс станет командой, которую вы выполнили.
Итак, теперь у вас есть процесс оболочки с дочерним элементом, который в вашем случае является командой ps
с -ef
атрибутами.
В этот момент родитель (оболочка) снова fork()
s. Этот недавно сгенерированный дочерний процесс close()
имеет свой стандартный дескриптор входного файла (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
не соответствует шаблону поиска в stdin, поскольку строка, содержащая «c», за которой следует «ron», не найдена, но обнаружена строка, содержащая «c», за которой следует «] ron»
GNU grep
не имеет ограничения на совпадение строк, а на некоторых платформах (я думаю, Solaris, HPUX, aix) предел строки задается переменной "$ COLUMN" или шириной экрана терминала.
Надеюсь, этот длинный ответ немного прояснит процесс оболочки.
Совет:
ps -ef | grep cron | grep -v grep