Intereting Posts
Должен ли я использовать жесткие ссылки для моей «привязанной к сайтам» папки вместо программных ссылок? Предотвращение вывода в / var / log / syslog Почему rm управляет непризнанным флагом w в AIX? Перемещение образа ОС Linux с флэш-накопителя 4 ГБ на жесткий диск gpg шифрование: ошибка в расшифровке с подтвержденным ключом и точная команда как прошлые успешные передачи Почему некоторые буквы или escape-последовательности не отображаются правильно в urxvt? Как работает опция -fuzzy для rsync? /etc/cron.hourly в домашнем каталоге Как начать сервис в systemd сразу после cryptsetup? Значение суммы рядом с определенным шаблоном Как отключить USB-устройства на основе их идентификатора поставщика в GNU / Linux? MATE: Плитка 2 окна рядом друг с другом В чем разница между этими двумя наборами команд для настройки разрешений ACL? Как проверить теневые носки, нормально ли работает на установленном сервере? Как обрабатывать строки с пробелами в целом в bash?

grep, вторгающийся в мой ps

Когда я проверяю какой-то процесс, я обычно пишу

ps aux | grep myprocess 

И иногда я получаю вывод

 eimantas 11998 0.0 0.0 8816 740 pts/0 S+ 07:45 0:00 grep myprocess 

если процесс не запущен.

Теперь мне действительно интересно, почему grep находится в списке процессов, если он отфильтровывает вывод команды ps после запуска ps ?

Такое поведение абсолютно нормальное, это связано с тем, как bash управляет использованием труб.

Труба реализуется с помощью bash, используя системный столбец pipe . После этого вызова bash вилки и заменяет стандартный ввод ( дескриптор файла 0 ) на вход из правого процесса ( grep ). Основной процесс bash создает другую вилку и передает выходной дескриптор fifo вместо стандартного ввода ( описание файла 1 ) и запускает левую команду.

Утилита ps запускается после команды grep , поэтому вы можете видеть ее на выходе.

Если вы не уверены в этом, вы можете использовать set -x для включения командной строки. Например:

 + ps aux + grep --color=auto grep + grep --color=auto systemd alexises 1094 0.0 0.8 6212 2196 pts/0 S+ 09:30 0:00 grep --color=auto systemd 

Для получения дополнительной информации вы можете проверить эту часть базовой c-оболочки: http://www.cs.loyola.edu/~jglenn/702/S2005/Examples/dup2.html

Когда меня интересует только наличие процесса, я использую pgrep, который не показывает этого поведения, например:

 $ pgrep myprocess 1900 

В других случаях (когда меня интересует больше информации), я обычно добавляю '| grep -v grep ', чтобы удалить строки grep, например:

 $ ps -ef | grep myprocess| grep -v grep 

НТН.

pipe не ведет себя так ; , Он запускает оба процесса вместе. Именно поэтому и появилась команда grep . Поэтому, когда вы дали ps aux | grep myprocess ps aux | grep myprocess , ps aux включал grep myprocess , поэтому grep включал это в свой вывод.

Чтобы проверить это, я дал две команды dd на моем тестовом сервере следующим образом:

[sreeraj@server ~]$ dd if=/dev/urandom of=/home/sreeraj/myfile1 bs=1M count=1024 | dd if=/dev/urandom of=/home/sreeraj/myfile2 bs=1M count=1024

И когда я проверил процесс dd , он показывает, что оба они начались в одно и то же время (посмотрите на coloumn, который говорит, что прошло 2:55 минут):

[sreeraj@server ~]$ ps aux | grep 'dd if' sreeraj 14891 100 0.2 5376 1416 pts/0 R+ 11:56 2:55 dd if=/dev/urandom of=/home/sreeraj/myfile1 bs=1M count=1024 sreeraj 14892 100 0.2 5376 1412 pts/0 R+ 11:56 2:55 dd if=/dev/urandom of=/home/sreeraj/myfile2 bs=1M count=1024 sreeraj 14936 0.0 0.1 9032 672 pts/1 S+ 11:59 0:00 grep --color=auto dd if [sreeraj@server ~]$

Теперь, если вы хотите исключить grep из вывода, используйте regex. Это исключает grep из результата:

 ps aux | grep "[m]yprocess" 

Например, если вы ищете httpd-процесс, используйте:

 ps aux | grep "[h]ttpd" 

Но я предлагаю вам использовать pgrep -a , который будет более надежным.

 [sreeraj@server ~]$ pgrep -a httpd 8507 /usr/sbin/httpd -DFOREGROUND 8509 /usr/sbin/httpd -DFOREGROUND 8510 /usr/sbin/httpd -DFOREGROUND 8511 /usr/sbin/httpd -DFOREGROUND 8513 /usr/sbin/httpd -DFOREGROUND 8529 /usr/sbin/httpd -DFOREGROUND [sreeraj@server ~]$ 

Вы правы, это не так, как это работает. Оболочка не дожидается завершения первого процесса в конвейере до начала следующего. Он начинает их всех. Таким образом, ps может видеть, что grep уже запущен.

Рассмотрим этот мысленный эксперимент: если ps закончил выполнение, прежде чем вызывать grep как вы думаете, это должно означать, что оболочке потребуется:

  1. Вызвать ps .
  2. Буфер все его выход (потому что ему еще больше некуда идти).
  3. Вызвать grep .
  4. Подайте сохраненный вывод на stdin grep .

Это расточительно; это более эффективное использование памяти для вызова grep первых, пусть оно ждет ввода, а затем ps stdout ps прямо в stdin grep .

Или, в крайнем случае, рассмотрим случай подачи вывода программы, которая генерирует бесконечный объем вывода, например:

 $ yes | less 

Если оболочка запускала yes раньше, вам оставалось ждать навсегда (или пока вы полностью не исчерпали память своего компьютера).

Просто подтверждая, что BowlOfRed и alexises заявили. Вот визуальное представление pips ps и grep обратно в ps снова, чтобы показать, как работают процессы в каналах. Обратите внимание, что окончательный ps x --forest игнорирует вход, но он сохраняет прежние процессы в каналах, чтобы они отображались.

ps -ef | grep myprocess | ps x --forest

Вывод:

 25056 pts/3 Ss 0:05 \_ bash 12243 pts/3 R+ 0:00 | \_ ps -ef 12244 pts/3 S+ 0:00 | \_ grep --color=auto myprocess 12245 pts/3 R+ 0:00 | \_ ps x --forest 

Уведомление bash находится в состоянии прерывистого сна S (ожидание завершения события). s указывает, что это лидер сеанса, как вы увидите ниже.

С -ef опции -ef вы также можете видеть, что дочерние процессы выполняются под одним и тем же идентификатором родительского элемента, который является идентификатором процесса bash , 25056 .

ps x | grep myprocess | ps -ef --forest

Вывод:

 UID PID PPID C STIME TTY TIME CMD iamuser 25056 16737 0 Dec23 pts/3 00:00:05 \_ bash iamuser 12161 25056 0 05:02 pts/3 00:00:00 | \_ ps x iamuser 12162 25056 0 05:02 pts/3 00:00:00 | \_ grep myprocess iamuser 12163 25056 0 05:02 pts/3 00:00:00 | \_ ps -ef --forest