Это вполне ожидаемое поведение, но, возможно, несколько запутанное, если вы точно не знаете, что на самом деле делают задействованные команды. И нет, нет никакого мошеннического программного обеспечения. Я постараюсь объяснить, что на самом деле здесь происходит.
Во-первых, при запуске ps ax
выдает список всех процессов, запущенных в системе, и (некоторые из них) их аргументы командной строки.
Во-вторых, когда вы запускаете grep "nginx"
, он будет читать со стандартного ввода (поскольку вы не указали файл, который будет использоваться в качестве ввода) и выводить любые строки, содержащие строку nginx
.
В оболочке Unix-подобной системы (такой как Mac OS X) каналы обычно реализуются таким образом, что, по сути, означает, что команды запускаются справа налево, а данные переносятся слева направо.
Итак, вот что происходит: сначала запускается grep
с аргументом nginx
. Во-вторых, ps
запускается с аргументом ax
, и его стандартный вывод связан со стандартным вводом процесса grep
. Когда ps
работает, его выход подается на стандартный вывод ps
, что аналогично стандартному вводу grep
. В свою очередь, grep
просматривает каждую строку в поисках строки nginx
, потому что это то, что вы сказали grep
делать. Такая строка появляется один раз: сам процесс grep со своими аргументами командной строки! В результате, эта строка печатается grep
на стандартный вывод Grep, а все остальные подавляются. В первом примере стандартный вывод grep не привязан ни к какому другому процессу, поэтому по умолчанию он выводится на терминал. Когда от ps
больше нет данных, grep
также завершается, потому что все команды связаны друг с другом; не имеет никакого реального смысла, чтобы один из них выполнялся, когда другой закончил.
Когда вы передаете вывод grep через awk
в xargs kill
, происходит следующее: xargs создает список того, что он собирается делать, но на самом деле не делает этого до конца. Таким образом, к тому моменту, когда xargs приступит к вызову kill, процесс grep, у которого nginx был одним из параметров командной строки, уже ушел. Следовательно, нет процесса отправки сигнала, и kill
уведомляет вас об этом факте.
Как вы можете видеть, в вашей системе не запущен мошеннический процесс nginx, уклоняющийся от ваших попыток найти его; есть только grep, который запускается многократно, по одному разу при каждом взгляде, который находит себя.
Вы можете избежать этого, используя группы символов где-то в строке поиска, потому что это не найдет себя. Например, ps ax | grep foobar
возвращает процесс grep, но ps ax | grep 'fooba[r]'
этого не делает, потому что fooba[r]
- это не то же самое, что foobar
при сравнении с простой строкой. ([r]
соответствует любому из символов r
, поэтому только r
.) Обратите внимание, что для того, чтобы сделать это, вам, вероятно, нужно избежать аргумента grep
.
Кроме того, почти всегда нет необходимости сначала запускать grep
а затем awk
без чего-либо другого между ними. Вместо ... | grep 'foobar' | awk '{ print $2 }'
для некоторой предыдущей команды ...
, вы можете просто использовать ... | awk '/foobar/ { print $2 }'
чтобы awk выполнял обе обязанности. Чаще всего это встречается с cat
, где это называется бесполезным использованием cat , но эта концепция хорошо подходит и для других команд, таких как grep в вашем случае.