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