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

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.
hmontoliu
источник
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]

jamzed
источник
Добавьте пробел, если вам нужен 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

ramruma
источник
Как обычно, я забыл упомянуть платформу (в данном случае 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 и отфильтровывает все остальное.
Кристофер Хантер