Как я могу предотвратить появление «grep» в результатах ps?
Когда я ищу какой-то процесс, который не существует, например
$ ps aux | grep fnord
wayne 15745 0.0 0.0 13580 928 pts /6 S + 03:58 0:00 grep fnord
Очевидно, что я не забочусь о grep - это имеет столько же смысла, сколько и поиск процесса ps
!
Как я могу предотвратить появление grep в результатах?
14 ответов
Оказывается, есть решение, найденное в брелка .
$ ps aux | grep "[f] nord"
Поместив скобки вокруг буквы и кавычки вокруг строки, которую вы ищете для регулярного выражения, в котором говорится: «Найдите символ« f », а затем« nord ».
Но так как теперь вы помещаете скобки в шаблон 'f', следует ']', поэтому grep
не будет отображаться в списке результатов. Neato!
Другая опция, которую я использую (особенно для того, чтобы посмотреть, работает ли процесс), является pgrep
команда. Это приведет к поиску соответствующего процесса, но не отобразит строку grep для поиска. Мне это нравится, потому что это быстрый способ поиска, без регулярного выражения или избежания чего-либо.
pgrep fnord
Идеальное решение - это предложение, представленное BriGuy
pgrep fnord
Но если вы не хотите этого делать, вы можете просто исключить все строки, которые соответствуют grep , с помощью:
ps aux | grep -v grep | grep "fnord"
Не самое элегантное решение, но вы можете это сделать:
$ ps aux | grep fnord | grep -v grep
В zsh, grep fnord = (ps aux)
.
Идея: сначала запустите ps aux
, поместите результат в файл, затем используйте grep
в этом файле. Только у нас нет файла, так как мы используем zsh-подстановку процесса.
Чтобы проиллюстрировать, попробуйте
ps aux> ps.txt
grep fnord ps.txt
rm ps.txt
Результат должен быть тем же.
Общий комментарий по некоторым другим ответам. Некоторые из них очень сложны и /или долго набираются. Дело не только в том, чтобы быть правильным, но и должно быть полезным. Но это не означает, что некоторые из этих решений плохие; только они должны быть завернуты в мини-интерфейс, чтобы сделать их пригодными для использования.
ps aux | grep $ (echo fnord | sed "s /^ \ (. \) /[\ 1] /g")
â < Этот ответ специфичен для GNU . См. ответ Уэйна для более общего решения.
Поиск процессов
Если вы просто ищете процессы fnord
, вы можете использовать опцию -C
для выбора по имени команды:
ps -C fnord
Это может быть смешано с вариантами формата в стиле BSD и POSIX по вашему вкусу. Полный список можно найти на странице ps man .
Ищете что-то другое?
Если вам нужно что-то более продвинутое, чем точный поиск имени команды, не теряйте надежды! Это все еще можно сделать на стороне ps
. Все, что нам нужно сделать, это сообщить ps
, чтобы исключить процессы grep
из результата:
ps -NC grep | grep 'fnord'
-C grep
выбирает все grep-процессы, а -N
отрицает выбор. Это можно использовать для поиска аргументов команды, части имени команды или более сложных регулярных выражений.
Мой ответ - это вариант типичного ответа на поиск «foobar» в листинге «ps». Аргумент «-A» «ps» более переносимый, чем «aux», я считаю, но это изменение не имеет отношения к ответу. Типичный ответ выглядит следующим образом:
$ ps -A -ww | grep [f] oobar
Вместо этого я использую этот шаблон:
$ ps -A -ww | grep [^]] foobar
Основное преимущество заключается в том, что писать сценарии на основе этих шаблонов проще, потому что вы просто объединяете статическую строку «[^]]» с любым шаблоном, который вы ищете. Вам не нужно снимать первую букву строки, а затем вставлять ее между квадратными скобками, а затем объединять ее снова. При написании сценариев в оболочке проще просто вставить «[^]]» перед шаблоном, который вы искали для поиска. Строка, разрезающая в Bash, является уродливой, поэтому моя вариация позволяет избежать этого. Этот вариант говорит, что строки, где шаблон соответствует WITHOUT, имеют правую квадратную скобку]. Так как шаблон поиска для исключения квадратной скобки фактически добавляет квадратную скобку к шаблону, он никогда не будет соответствовать самому себе.
Итак, вы можете написать переносимую команду psgrep следующим образом. Здесь я делаю некоторые различия между Linux, OS X BSD и другими. Это добавляет заголовки столбцов из «ps», предоставляет более настраиваемый формат «ps», который соответствует моим потребностям, и отображает процессы, перечисляющие дополнительные, дополнительные широкие, чтобы ни один из аргументов командной строки не был пропущен. Ну, большинство не пропустили. Java, являющаяся Java, часто делает вещи наихудшим образом, так что некоторые java-сервисы будут проходить мимо максимально допустимой длины аргументов, которые будет отслеживать таблица процессов. Я считаю, что это 1024 символа. Длительность командной строки, разрешенная для запуска процесса, намного длиннее, но таблица процессов ядра не мешает отслеживать что-либо более 1 КБ. После запуска команды список команд и имен не требуется, поэтому данные, хранящиеся в таблице процессов, являются информативными.
psgrep ()
{
шаблон = [^]] $ {1};
case "$ (uname -s)" в
Дарвин)
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}
;;
*) # другие вкусы UNIX получают минималистскую версию.
ps -A -ww | grep -i -e $ {pattern}
;;
ESAC
}
Простейшим способом выполнения этого метода является его сохранение в переменной:
PS_OUTPUT = "$ (ps aux)"; echo "$ PS_OUTPUT" | grep fnord
Вызов: @ EmanuelBerg's grep fnord = (ps aux)
ответ, безусловно, самый изящный, хотя для него требуется zsh
. Я кратко использовал его в своих rc-файлах, но bash жалуется на этот синтаксис даже несмотря на условие, которое должно помешать его оценке.
Из моих rc-файлов у меня есть версия без учета регистра, которая принимает аргументы grep:
psl () {
local PS_OUTPUT = "$ (ps auxww)"
echo "$ {PS_OUTPUT %% $ '\ n' *}"> & 2 # title, в stderr, чтобы избежать труб
echo "$ {PS_OUTPUT # * $ '\ n'}" | grep -i "$ {@: - ^}"
}
Прогулка по коду, одна пуля на строку кода:
- Захватите подробный вывод
ps
(в переменнойlocal
, чтобы он исчез, когда функция завершена). - Отобразить первую строку (заголовок) в стандартной ошибке, чтобы результаты могли быть дополнительно отфильтрованы без влияния на заголовок. Подстановка говорит: возьмите $ PS_OUTPUT и удалите все после первого фида строки (regex equiv:
s /\ n. * $ //msg
). Это не позволяет нам загорать заголовок. - Отобразите вывод
ps
со всем кроме первой строки (regex equiv:s /^.* \ n //m
) и grep его содержимое с помощью-i
для нечувствительности к регистру и со всеми аргументами, переданными этой функцией, или, в случае отсутствия аргументов,^
, (в соответствии с началом любая строка, которая соответствует всем).
Возможно, на этот раз можно использовать настоящую последовательность. Использование труб делает его параллельным.
ps aux> f & & grep tmpfs <f
Ужасно, потому что будет файл f
, но это не моя ошибка, что нет синтаксиса для последовательных процессов, в которых вы все еще хотите использовать вывод предыдущего процесса.
Предложение синтаксиса последовательного оператора:
ps aux ||| grep tmpfs
Команда pgrep, как заявили другие, вернет идентификатор PID (идентификатор процесса) процессов на основе имени и других атрибутов. Например,
pgrep -d, -u <имя_пользователя> & Lt; & строка GT;
предоставит вам идентификаторы PID, разделенные запятой (,) всех процессов, имя которых совпадает с именем пользователя <username>
. Вы можете использовать ключ -x раньше, чтобы возвращать только точные соответствия.
Если вы хотите получить более подробную информацию об этих процессах (как предполагает использование опций aux из ps), вы можете использовать опцию -p с ps, которая соответствует основанию PID. Так, например,
ps up $ (pgrep -d, -u <имя_пользователя> <string>);
предоставит подробную информацию обо всех PID, соответствующих команде pgrep.
Вот простой пример для поиска 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 # сделать псевдоним полезным
mygrep $ {USER} $ {PROCESS_PATH}
mygrep $ {USER} "[f] nord"
mygrep "[f] nord"
mygrep ". * [s] shd"
P.S. Я тестировал эти команды только на Ubuntu и Gentoo.
Использование опции -x (точное совпадение) работало для меня. Я объединил его с -f (полная командная строка), поэтому я мог точно совместить свой процесс с помощью:
pgrep -x -f "path_i_used_when_starting /cmd params_i_used"
Вы можете сделать это легко, просто с определением ALIAS в .bashrc
например:
alias grep = 'grep -v grep | Grep»