Это вполне ожидаемое поведение, но, возможно, несколько запутанное, если вы точно не знаете, что на самом деле делают задействованные команды. И нет, нет никакого мошеннического программного обеспечения. Я постараюсь объяснить, что на самом деле здесь происходит.
Во-первых, при запуске 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 в вашем случае.