Как предотвратить "ps", сообщающий о своем собственном процессе?

$ 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)?

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

7 ответов

Решение

Мой ответ - это вариант типичного ответа для поиска "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
}

+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.

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]

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

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

ps | grep django | grep -v grep

ps -d | grep django

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

 -d                  Lists information  about  all  processes
                     except session leaders.

Это происходит со мной только при запуске команды «скрипта» ssh или при использовании инструментов удаленного управления. Мне не нравится хакерство предыдущих решений. Я не уверен, что то, что я придумал, лучше, но вот:

      | grep -v $$

$$ заменяется PID «процесса» ps/pgrep, а -v сообщает grep не печатать его.

демо:

      watch date &
bash -c 'echo; pgrep -lfa watch | grep -v $$'

тотbash -cиechoнеобходимы только для моделирования упомянутой ситуации и потому, что в противном случаеpgrepне сообщил бы о себе.

Другие вопросы по тегам