Как не допустить, чтобы «пс» сообщал о собственном процессе?


52
$ ps | grep django
28006 ttys004    0:01.12 /usr/bin/python bin/django celeryd --beat
51393 ttys005    0:01.45 /usr/bin/python bin/django celeryd -l INFO
51472 ttys005    0:01.29 /usr/bin/python bin/django celeryd -l INFO
51510 ttys005    0:01.89 /usr/bin/python bin/django celeryd -l INFO
51801 ttys005    0:01.83 /usr/bin/python bin/django celeryd -l INFO
53470 ttys005    0:03.97 /usr/bin/python bin/django celeryd -l INFO
53780 ttys005    0:00.00 grep django

Есть ли способ предотвратить сообщение о последнем процессе (то есть, grep, который был запущен одновременно с моей командой ps)?

(Я начал пытаться придумать регулярное выражение, которое бы соответствовало буквальному, но не соответствовало само по себе, но это, казалось, не совсем правильный подход ...)

Ответы:


14

Мой ответ - это вариант типичного ответа для поиска «foobar» в psлистинге. Аргументация "-A" "ps"является более переносимой, чем "aux", я полагаю, но это изменение не имеет отношения к ответу. Типичный ответ выглядит так:

$ ps -A -ww | grep [f]oobar

Вместо этого я использую этот шаблон:

$ ps -A -ww | grep [^]]foobar

Основное преимущество заключается в том, что на основе этих шаблонов легче писать сценарии, поскольку вы просто объединяете статическую строку [^]]с любым шаблоном, который ищете. Вам не нужно удалять первую букву строки, затем вставлять ее между квадратными скобками, а затем снова объединять ее. При создании сценариев в оболочке проще просто придерживаться [^]]шаблона, который вы искали. Разрезание строк в Bash - отвратительная вещь, поэтому мой вариант этого избегает. Этот вариант говорит о том, что показывают линии, в которых шаблон соответствует БЕЗ ведущей правой квадратной скобки]. Поскольку шаблон поиска для исключения квадратной скобки фактически добавляет квадратную скобку к шаблону, он никогда не будет совпадать сам по себе.

Таким образом, вы можете написать переносимую psgrepкоманду следующим образом. Здесь я делаю некоторые различия между Linux, OS X BSD и другими. Это добавляет заголовки столбцов ps, обеспечивает более настраиваемыйpsформат, который мне больше подходит, и отображает процессы, перечисляющие дополнительные, очень широкие, так что ни один из аргументов командной строки не будет пропущен. Ну, большинство не пропустили. Java - это Java, она часто работает в наихудшем из возможных способов, поэтому некоторые java-сервисы будут работать с максимально допустимой длиной аргументов, которую будет отслеживать таблица процессов. Я считаю, что это 1024 символов. Длина в одиночку, позволяющая запустить процесс, намного длиннее, но таблица процессов ядра не заботится о том, чтобы отслеживать что-то более 1 КБ. Когда команда запущена, имя команды и список аргументов не нужны, поэтому то, что хранится в таблице процессов, является просто информационным.

psgrep ()
{
    pattern=[^]]${1};
    case "$(uname -s)" in
        Darwin)
            ps -A -ww -o pid,ppid,nice,pri,pcpu,pmem,etime,user,wchan,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        Linux)
            ps -A -ww -o pid,ppid,tid,nice,pri,pcpu,pmem,etime,user,wchan:20,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        *)  # other UNIX flavors get a minimalist version.
            ps -A -ww | grep -i -e ${pattern}
        ;;
    esac
}

Недостатком является то, что это на самом деле будет соответствовать на один символ больше (впереди), чем оригинальный шаблон. Например, это никогда не будет соответствовать PID. И может быть немного вводит в заблуждение при использовании с grep --colour.
— Тонин

67

+1 для краткого ответа @jamzed, однако ОП может потребоваться некоторое объяснение:

ps | grep "[d]jango"

Используя это регулярное выражение, вы запускаете процесс, которому его строка ps не будет соответствовать сама по себе, поскольку регулярное выражение совпадает "django"и нет "[d]jango". Таким образом, вы исключите процесс со строкой «[d] jango», в данном случае это grep; То же самое можно применить к pgrep, egrep, awk, sed и т. Д., Какую бы команду вы не использовали для определения регулярного выражения.

От человека 7 регулярное выражение

   A bracket expression is a list of characters enclosed in "[]".  It nor‐
   mally matches any single character from the list (but see  below).   If
   the  list  begins  with  '^',  it matches any single character (but see
   below) not from the rest of the list.  If two characters  in  the  list
   are  separated  by '-', this is shorthand for the full range of charac‐
   ters between those two (inclusive) in the collating sequence, for exam‐
   ple,  "[0-9]" in ASCII matches any decimal digit.  It is illegal(!) for
   two ranges to share an endpoint, for example, "a-c-e".  Ranges are very
   collating-sequence-dependent,  and portable programs should avoid rely‐
   ing on them.

2
Здорово. Я на самом деле довольно комфортно с регулярными выражениями, но не мог сразу придумать, как предотвратить соответствие регулярных выражений. Заключение буквы в квадратные скобки имеет смысл. (Включая что-то вроде [^!] Также будет работать ...)
— Стив Беннетт

1
Это мило и хитро.
— Пеп

Для конкретного случая 'ps' я использую '[]' в начале имени процесса, который я ищу. Тогда мне не нужно анализировать имя процесса специально для регулярного выражения, но оно все равно совпадает.
— Neromancer

@hmontoliu Она не работает, например: ps aux | grep [s]cript1. Не могли бы вы помочь прокомментировать решение?
— SOUser

@hmontoliu Моя вина. Кажется, что линия показана из-за предыдущих поисков ...
— SOUser

30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


Добавьте пробел, если вам нужен grep один символ:ps aux| grep "[Z] "
— AD

@jamzed Это не работает, например: ps aux | grep [s]cript1или ps aux | grep [s]cript2. Строка grep по-прежнему отображается. Не могли бы вы помочь прокомментировать решение?
— SOUser

@ jamzed Моя вина. Кажется, что линия показана из-за предыдущих поисков ...
— SOUser

18

Вместо этого используйте pgrep: pgrep -lf django


Как обычно, я забыл упомянуть платформу (в данном случае OS X). Предположительно pgrep работает на разных linux.
— Стив Беннетт

Я не согласен, @ramruma. Я пришел к этой теме именно потому, что pgrepдает мне именно эту проблему. Но я должен сказать, что я тестирую его в CygWin (где psне может показать полную командную строку процесса).
— Сопалахо де Арриерес

В руководстве говорится: «Запущенный процесс pgrep или pkill никогда не будет сообщать о себе как о совпадении», и на самом деле я этого не видел.
— Deltab

Я только что столкнулся с проблемой, когда я подумал, что pgrepона совпадает сама по себе. Оказывается, оно совпадало с именем bashфайла скрипта, из которого я его запускал. Добавление -xисправило это, тогда это делает точное совпадение с именем команды.
— andynormancx

11

Ой, подождите, это работает:

ps | grep django | grep -v grep

7
Только в том случае, если командная строка процесса не имеет законного значения grep, на которое вы не можете рассчитывать в общем случае.
— CVn

8

ps -d | grep django

от человека PS:

 -d                  Lists information  about  all  processes
                     except session leaders.

все еще показывает grep на моем ...
— Кевин

Да, это работает для меня на OS X.
— Стив Беннетт

Не очень хорошо работает на Linux.
— Acumenus

В более общем смысле, варианты, psкак известно, непереносимы, поэтому без информации о том, для какой платформы это нужно , этот ответ не очень полезен. Более того, этого явно недостаточно, если вы не уверены, что искомый процесс не является лидером процесса (т. Е. Это может помочь, если ваша цель - демон, но обычно это не так).
— tripleee

Забавно, но на Mac это только показывает процесс grep и отфильтровывает все остальное.
— Кристофер Хантер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.