Как я могу предотвратить 'grep' от разоблачения в результатах PS?

Попробуйте следующую команду, тот список название каждого установленного пакета, который имеет строку "metapackage" в его поле раздела в apt-cache show вывод:

apt-cache show $(dpkg-query -Wf '${Package}\n') | 
  awk '$1 == "Package:" { pkg = $2 }; 
       $1 == "Section:" && $2 ~ /metapackage/ { print pkg }'
316
30.04.2013, 16:44
16 ответов

Повороты там являются решением, найденным в связке ключей.

$ ps aux | grep "[f]nord"

Путем помещения скобок вокруг буквы и кавычек вокруг строки Вы ищете regex, который говорит, "Найдите символ 'f' сопровождаемый 'nord'".

Но так как Вы помещаете скобки в шаблон 'f', теперь сопровождается']', таким образом, grep не обнаружится в списке результатов. Neato!

448
27.01.2020, 19:26
  • 1
    @acolyte: вывод от PS будет включать строку, заканчивающуюся grep [f]nord. Однако та строка не сделает в через фильтр grep, потому что строка [f]nord не соответствует регулярному выражению [f]nord. –  LarsH 30.04.2013, 20:58
  • 2
    @LarsH, Спасибо! я предложил бы ps aux | grep fnord | grep -v grep ... который, кажется, был уже предложен несколькими людьми... lol –  acolyte 30.04.2013, 21:16
  • 3
    @progo Да, действительно необходимо заключить в кавычки [ даже в ударе. Попробуйте его названным файлом fnord в текущем каталоге. –  Gilles 'SO- stop being evil' 02.05.2013, 01:18
  • 4
    Grepping вывод ps может быть старый прием, но это ненадежно. Использовать pgrep при наличии. –  Gilles 'SO- stop being evil' 02.05.2013, 01:19
  • 5
    @naxa Предполагает, что у Вас есть вызов программы fnord и названная программа safnorde. Или существует позвонивший пользователь bfnord, и Вы заканчиваете тем, что уничтожили все его процессы. И т.д. –  Gilles 'SO- stop being evil' 25.11.2013, 00:37

Возможно, время для использования реальной последовательности на этот раз. Использование каналов заставляет его быть параллельным.

ps aux >f && grep tmpfs <f

Ужасный, потому что будет файл f, но это не мой отказ, что нет никакого синтаксиса для последовательных процессов, где Вы все еще хотите использовать вывод ранее выполненного процесса.

Предложение для синтаксиса последовательного оператора:

ps aux ||| grep tmpfs
0
27.01.2020, 19:26
  • 1
    , который неспособность простых людей легко отфильтровать поток является едва причиной для элиты основывать самих с последовательностями. Это был бы шаг назад в вычислениях. –  Acumenus 18.08.2014, 23:27
  • 2
    @A-B-B en.wikipedia.org/wiki/Communicating_sequential_processes имеет намного больше операторов, чем те, которые закончили в оболочке Thompson. Возможно, просто был оператор, который последователен, и который передал его результат к следующему процессу в последовательности как только его выходы. "Шаг назад в вычислениях" путем обеспечения дополнительного оператора кажется немного резким. –  Anne van Rossum 19.08.2014, 10:09
  • 3
    Хорошая ссылка, но конечно последовательная обработка хуже и в ЦП и в памяти (или диск) использование - относительно параллельной обработки. В этом экземпляре, если я должен сначала сохранить все ps вывод, прежде чем я grep, Я использую больше памяти (или диск) для дольше. –  Acumenus 19.08.2014, 22:37

В zsh, grep fnord =(ps aux).

Идея, первый показ ps aux, поместите результат в файл, затем используйте grep на том файле. Только, у нас нет файла, поскольку мы используем "замену процесса zsh".

Для иллюстрирования попробовать

ps aux > ps.txt
grep fnord ps.txt
rm ps.txt

Результатом должно быть то же.

Замечание общего порядка о некоторых из других ответов. Некоторые далеки к сложному и/или длинному для ввода. Это не только вопрос того, чтобы быть правильным, это должно быть применимо также. Но это не означает, что некоторые из тех решений плохи; только, они должны быть перенесены в мини-UI для создания их применимыми.

15
27.01.2020, 19:26
  • 1
    Не зная замены процесса zsh, но действительно ли бесспорно, что два процесса называют один за другим и не параллельно? –  Paŭlo Ebermann 01.05.2013, 13:17
  • 2
    : Поскольку параллель <(command). grep grep =(ps aux) не показывает строки. –  Maciej Piechotka 01.05.2013, 17:17
ps aux | grep $(echo fnord | sed "s/^\(.\)/[\1]/g")
7
27.01.2020, 19:26
  • 1
    это похоже на IOCCC, но для командной строки Unix вместо C ^^ Просто | grep $(echo fnord) не был достаточно? Вы также просите, чтобы sed искал и заменил каждый символ в "fnord" его собственным значением? ^^ поздравляю. Я держал пари, что могу сделать еще более длинный, но это, вероятно, не будет как забавный ^^ –  Olivier Dulac 30.04.2013, 19:26
  • 2
    я приношу извинения как тон моего выше комментария, может звучать оскорбительным (и я не могу отредактировать его после 5 млн)... Ваш ответ был действительно радостным чтением, и я не пытался заставить Вас выглядеть плохо. Я действительно думаю, что Вы сделали это как это нарочно ^^ –  Olivier Dulac 30.04.2013, 19:31
  • 3
    Не приносите извинения, Ваш ответ был действительно забавой читать (и пятно - на праве также). Я имел в виду pgrep-l 1$ так или иначе ;) –  yPhil 30.04.2013, 19:48
  • 4
    @OlivierDulac: Он только заменяет первый символ его собственным значением; он заменяет его конкатенацией его значения среди квадратных скобок. (Те квадратные скобки не являются особенными, они являются литеральными.) В основном, он делает вывод на ответе Wayne Werner, так, чтобы процесс помещения квадратных скобок вокруг первого символа мог быть задан сценарием. +1 –  LarsH 30.04.2013, 21:02
  • 5
    ps aux | grep '[^]]fnord' избежал бы что гимнастический. –  Stéphane Chazelas 30.04.2013, 23:21

Не самое изящное решение, но Вы могли сделать это:

$ ps aux | grep fnord | grep -v grep

26
27.01.2020, 19:26
  • 1
    Это - плохой ответ! Поскольку, если было слово grep в Вашей фразе. Это не покажет тот процесс. Например, предположите названный файл foo_grep_bar.txt редактируется nano команда. Таким образом, существует выполнение процесса: root 14908 0.0 0.0 110012 1692 pts / 3 S + Oct31 0:00 nano foo_grep_bar.txt Согласно этому ответу, это не будет работать: $ ps aux | grep nano | grep -v grep Поскольку существует grep слово в Вашем имени файла. –  Nabi K.A.Z. 01.11.2017, 01:33
  • 2
    я предпочитаю это как его более явное о его намерении, чем принятый ответ и работы во всех кроме одного случая. –  samaspin 28.03.2018, 14:20

Идеальное решение является тем, представленным BriGuy

pgrep fnord 

Но если Вы не хотите делать это, можно просто исключить все строки, который соответствует grep с:

ps aux | grep -v grep | grep "fnord"
64
27.01.2020, 19:26
  • 1
    , но что, если строка я ищу, "удар удара grep удар"? –  Sparr 30.04.2013, 23:27
  • 2
    @Sparr Затем необходимо использовать лучшее решение: pgrep или найдите другой ;) –  RSFalcon7 01.05.2013, 18:15
  • 3
    Не упустите предел длины имени с pgrep. Используйте-f для получения имени полного пути, или Вы могли бы найти свой сбой соответствий с более длинными именами.-l хорош также перечислить соответствия –  Neil McGill 16.12.2014, 16:32

Другая опция, которую я использую (особенно только, чтобы посмотреть, если процесс работает) pgrep команда. Это будет искать процесс соответствия, но не перечислять grep строку для поиска. Мне нравится он, потому что это - быстрый способ поиска без regexing или выхода из чего-либо.

pgrep fnord
171
27.01.2020, 19:26
  • 1
    Они захотят -f опция больше быть похожими ps | grep. –  jordanm 30.04.2013, 17:16
  • 2
    @jordanm На самом деле, pgrep -f посмотрит больше как ps -f | grep. интересный –  michelpm 30.04.2013, 21:09
  • 3
    Существует также -l аргумент, чтобы заставить его показать команду это подбирается. –  Patrick 01.05.2013, 06:34
  • 4
    ps | grep '[f]nord' является умным и почтенным, но pgrep является правильным. –  kojiro 01.05.2013, 14:33
  • 5
    Можно всегда делать ps $(pgrep cmd) ... если 'pgrep пропустит опции (то это не будет работать на пустое множество команд хотя). –  Maciej Piechotka 01.05.2013, 17:18

Команда pgrep, как другие заявили, возвратит PID (идентификатор процесса) процессов на основе имени и других атрибутов. Например,

pgrep -d, -u <username> <string>

даст Вам PIDs, разграниченный запятой () всех процессов чьи соответствия имени, выполняемые пользователем <username>. Можно использовать переключатель-x прежде для возврата только точных совпадений.

Если Вы хотите получить больше информации об этих процессах (поскольку выполнение aux опций от PS подразумевает), можно использовать-p опцию с PS, который соответствует на основе PID. Так, например,

ps up $(pgrep -d, -u <username> <string>)

даст подробную информацию всего PIDs, подобранного командой pgrep.

0
27.01.2020, 19:26
  • 1
    ps сбои, если pgrep возвращает пустое множество. У меня есть ответ, который полагается на Ваш и пытается решить эту проблему. –  Acumenus 19.08.2014, 20:00

Самым простым способом диагностики с помощью оболочки было бы сначала сохранить ее в переменной:

PS_OUTPUT="$(ps aux)"; echo "$PS_OUTPUT" |grep fnord

Call-out: Ответ Эмануэля Берга grep fnord =(ps aux) является, безусловно, самым элегантным, хотя он требует zsh. В моих rc-файлах он был вкратце, но bash жалуется на этот синтаксис, даже несмотря на условие, которое должно помешать его оценке.


Из моих rc файлов у меня есть версия, не чувствительная к регистру, которая принимает аргументы grep'а:

psl() {
  local PS_OUTPUT="$(ps auxww)"
  echo "${PS_OUTPUT%%$'\n'*}" >&2  # title, in stderr to avoid pipes
  echo "${PS_OUTPUT#*$'\n'}" |grep -i "${@:-^}"
}

ход кода, по одной пуле на строку кода:

  • захват многословного ps вывода (в переменной локальной, так что он исчезает, когда функция возвращается)
  • отображение первой строки (заголовка) в стандартной ошибке, так что результаты могут быть отфильтрованы в дальнейшем, не затрагивая заголовок. Замена говорит: take $PS_OUTPUT и remove everything after the first line feed (regex equiv: s/\n.*$//msg). Это предотвращает смазывание заголовка
  • Отображение вывода ps со всем , кроме первой строки (regex equiv: s/^. *\n//m) и grep ее содержимым с -i для нечувствительности к регистру и со всеми переданными аргументами этой функции (в случае отсутствия аргументов, ^, которая совпадает с началом любой строки, чтобы соответствовать всему)
2
27.01.2020, 19:26

Вы можете сделать это легко, просто указав АЛИАС в вашем .bashrc следующим образом:

alias grep='grep -v grep | grep'
-3
27.01.2020, 19:26

Вот простой пример поиска PID ssh-agent для имени пользователя без отображения PID процесса grep сам:

ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print $1 $2;}'

Если вы хотите, например, убить ssh-agent для текущего пользователя, вы можете использовать следующую команду:

kill `ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print $2;}'`

Чтобы создать удобный псевдоним, добавьте к вашему ~ / .bashrc или ~ / .zshrc запишите следующий код:

function function1 () {
    ps xu | grep "$1.*$2" | awk '{print $1" "$2" "$11;}'
}
alias mygrep="function1"

А вот примеры использования псевдонима, чтобы заставить всех изучать регулярные выражения:

. /etc/profile #to make alias usable
mygrep ${USER} ${PROCESS_PATH}
mygrep ${USER} "[f]nord"
mygrep "[f]nord"
mygrep ".*[s]shd"

PS Я тестировал эти команды только на Ubuntu и Gentoo.

0
27.01.2020, 19:26

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

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

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

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

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

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

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
}
3
27.01.2020, 19:26

Этот ответ специфичен для GNU . См. ответ Уэйна для более общего решения.

Поиск процессов

Если вы просто ищете процессы fnord , вы можете использовать параметр -C для выбора по имени команды:

ps -C fnord

Это может быть смешанный с вариантами формата в стиле BSD и POSIX по своему вкусу. См. Полный список на странице ps .

Ищете что-то еще?

Если вам нужно что-то более продвинутое, чем точный поиск имени команды, не теряйте надежды! Это все еще можно сделать на стороне трубы ps . Все, что нам нужно сделать, это указать ps исключить процессы grep из результата:

ps -NC grep | grep 'fnord'

-C grep выбирает все процессы grep, а -N отменяет выбор. Это можно использовать для поиска аргументов команды, части имени команды или более сложных регулярных выражений.

7
27.01.2020, 19:26

Мне помогло использование опции -x (точное совпадение). Я объединил его с -f (полная командная строка), поэтому я мог точно сопоставить свой процесс с:

pgrep -x -f "path_i_used_when_starting/cmd params_i_used"
0
27.01.2020, 19:26

Вот расширенная версия решения grep -v grep,фильтрация всех процессов grep, которые не выполнялись более секунды, что является улучшением по сравнению с «просто отбросить все вхождения grep».

$ ps -ef | grep -vw "00:00:00 grep" | grep <searchTerm>

соответственно

$ ps aux | grep -vw "0:00 grep" | grep <searchTerm>

Это может быть непереносимо и зависит от фактического формата вывода вашей локальной команды ps.

Возможно, вы захотите объединить это с цветным grepвыводом для удобства:

$ alias grep='grep --color=auto'
1
27.01.2020, 19:26

Обрабатывая ответы @Emmanuel -Berg & @Adam -katz, вы можете использовать параметр POSIX «-f $file» вместе с «Process Substitution» Bash «< ($cmd )":

$ ps aux | grep -f <( echo fnord)

Шаблон передается в grepчерез псевдофайл -, заполняемый командой echo fnord. Вы можете использовать эту удобную форму, которая позволяет использовать несколько шаблонов(fnord+syslog)вместо одного :

.
$ alias psgrep='ps aux | grep -f <( echo -e "$a")'
$ a="fnord\nsyslog"; psgrep
0
31.03.2021, 14:49

Теги

Похожие вопросы