Pull to refresh

Comments 48

hint: чтоб не находить сам grep в ps | grep, я оборачиваю одну букву в квадратные скобки.
то есть не `ps | grep asterisk` а `ps | grep [a]sterisk`
а еще удивлён, что ngrep помер… я им всего-то года два назад активно пользовался

Спасибо, так действительно нет рекурсии. Интересно, за счет чего выпадает ps | grep из вывода?

потому что у нас есть процесс с именем «grep asterisk», и он попадает под маску «asterisk».
а «grep [a]sterisk» НЕ попадает под маску «asterisk», из-за квадратных скобок.

Квадратные скобки означают «набор из одного символа a».
psgrep() { ps up $(pgrep -f $@) 2>&-; }

$ psgrep firefox
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
valdikss 29815  0.0  0.0 118988  2756 ?        S    Nov30   0:00 /bin/sh /usr/local/bin/firefox
valdikss 29817  0.0  0.0   9884  2116 ?        S    Nov30   0:00 firejail firefox
valdikss 29818  0.0  0.0   9884  1968 ?        S    Nov30   0:00 firejail firefox
valdikss 29821 19.5 11.0 11270608 887336 ?     Sl   Nov30 182:04 /usr/lib64/firefox/firefox

Спасибо! А то я всегда делал
ps | grep asterisk | grep -v grep

А я и дальше так буду делать, потому как предназначение квадратных скобок не очевидно настолько, насколько может быть не очевидно. Явно лучше чем неявно, не считая того, после вставки текста для grep мне нужно перемещаться куда-то и его редактировать. Но теперь у меня есть pgrep и я этому счастлив
не забываем, что grep ищет еще и по аргументам, а pgrep (по умолчанию) только по имени процесса.

ну и еще один простой способ — добавить \\ перед любой буквой.

например
`ps | grep asteris\\k`
А почему именно ps+grep? Мне кажется, добавить один флаг pgrep проще, чем писать конвейер. Да и есть этот pgrep даже в busybox (разве что, флаг -a там отстутствует, иногда не хватает).
потому, что pgrep это еще одна сущность, чтоб держать в голове.
опять же, ps+grep ищет еще по пидам (да, это удобно иногда).

опять же, вывод разный:

~$ ps -aux | grep nt\\p
ntp 4249 0.0 0.0 22960 1920? Ss нояб.29 0:12 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 117:125

~$ ps -aux | pgrep ntp
4249

~$ ps -aux | pgrep -a ntp
4249 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 117:125

как у pgrep искать по тредам? и еще миллион вариантов
то есть не `ps | grep asterisk` а `ps | grep [a]sterisk`

Добавлю ещё, что Николай ZyXI убедил меня (по крайней мере для Bash) брать часть содержащую раскрывающуюся символьный класс в кавычки. Аргументы:
Трюк пропадёт в никуда, если в каталоге есть файл XXXX

[alex@d /usr/home/Alex]$ ps afx | grep ntpd
656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
38412 0 S+ 0:00.00 grep ntpd
[alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
[alex@d /usr/home/Alex]$ touch ./ntpd
[alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
38435 0 S+ 0:00.00 grep ntpd
[alex@d /usr/home/Alex]$ ps afx | grep "[n]tpd"
656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
[alex@d /usr/home/Alex]$ rm ./ntpd
[alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
656 - Ss 0:57.57 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
[alex@d /usr/home/Alex]$
ну так это просто трюк для «здесь и сейчас», не для скриптинга. для скриптинга следует использовать pidof / pgrep / etc.

вариант с двумя слешами иммунен к файлу
вариант с двумя слешами иммунен к файлу

Ни в коем разе не придираюсь, но таки и этот вариант не безгрешен, например:
[alex@d /usr/home/Alex]$ touch ttyv1
[alex@d /usr/home/Alex]$ ps afx | grep ttyv1
3805 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1
43929 0 S+ 0:00.00 grep ttyv1
[alex@d /usr/home/Alex]$ ps afx | grep ttyv\\1
grep: Invalid back reference
[alex@d /usr/home/Alex]$ ps afx | grep "ttyv[1]"
3805 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1
[alex@d /usr/home/Alex]$

То есть луше всё-таки закавычивать.
«перед любой буквой», это да, важно.

во всяком случае, еще не напарвался над тем, чтоб не работало :)
(еще раз, на всякий случай, disclaimer: это НЕ для скриптинга, это для ad-hoc разбирательств)
UFO landed and left these words here
«grep -v grep» тоже не панацея, так как ломает, например, любые процессы которые работают с файлом с именем tobegrepped, например :)
UFO landed and left these words here

А теперь вы хотите найти strace, в котором запущен какой‐то другой grep

Ну если уж принципиально не использовать квадратные скобки исключаем тривиальный вариант:
$ ps afx | grep -w "[g]rep" | grep -vF "[g]rep"
30596 pts/13 S+ 0:00 | \_ strace grep . /dev/random
30599 pts/13 S+ 0:00 | \_ grep . /dev/random

и делаем с круглыми:
$ ps afx | grep -w "grep" | grep -vE "(grep).*\1"
30596 pts/13 S+ 0:00 | \_ strace grep . /dev/random
30599 pts/13 S+ 0:00 | \_ grep . /dev/random

:)
А можно разжевать подробнее как это работает. Оба варианта.
Понял что оба работают, но не понял почему.
$ ps afx | grep -w "[g]rep" | grep -vF "[g]rep"
в 1-м grep символьный класс [g] раскрывается в g, то есть поиск происходит по слову grep, а в список процессов попадает [g]rep. Вторым грепом мы его исключаем из списка, так как благодаря -F [g] не раскрывается.

$ ps afx | grep -w «grep» | grep -vE "(grep).*\1"
Здесь используется специальная конструкция \1 которая позволяет обратиться к уже найденной с помощью символов группировки подстроке, и данная строка использованием -v исключается из списка.

Всё это, конечно лучше делать с помощью pgrep и т.п. Вероятность накосячить в скриптах в таких конструкциях близка к 100%
UFO landed and left these words here

Если я хочу получить номер процесса в каком‐то скрипте, то ps afx | grep я вряд ли буду когда‐либо использовать: есть ps -C, killall (нет, pgrep я обычно не использую). Если мне нужен номер процесса или что‐то ещё посмотреть самому (даже и с целью передать потом «нужные» номера kill, скорее всего, просто переписав), то заморачиваться с исключением grepа мне не нужно вообще.


Здесь я просто показываю, что ps afx | grep — не лучший выбор, если нужна точность. Тот же strace с grepом проще искать через ps -C strace -o pid=,cmd= | grep -w grep (да, ps | grep, но второй grep тут в списке не покажется никогда, как и собственно процесс, запущенный под strace). Единственное но: -C не работает в cygwin и в BSD системах.

вообще, чтоб пид получить лучше всего pidof имхо. еще и читабебельнее

Для «ручного» поиска ps лучше: поискали, не нашли, исправили что‐то, нашли, убрали ненужные столбцы из -o, дописали pipe (или, как я чаще делаю, просто переписали PID). С pidof будет много возни, когда вы захотите проверить результаты поиска, или если внезапно обнаружите, что вам, на самом деле, нужно ещё уточнить, с какими аргументами программа запущена. Проще выучить один ps и всегда использовать его, чем переколбашивать командную строку для использования pidof, а в скриптах я предпочитаю использовать знакомые инструменты.

Pdfgrep не поддерживает расширенные регулярные выражения

Но поддерживает POSIX и PCRE?..

Что странно, системные вызовы read все время одни и те же, вне зависимости от поиска.
А с чего бы им отличаться? Как читал файл, так и читает, просто потом сравнивает содержимое буфера с разными строками.
Гораздо интересней не чтобы слово grep было в названии исполняемого файла, а схожесть функционалу.
тот же zgrep не умеет работать с ключом -R, чтобы искать по всем файлам в каталоге.
А вот есть пакет silversearcher-ag и в нем есть утилита ag. Она это умеет.
Помню, как при помощи pdfgrep анализировал проприетарную программу, которая наиболее полный output делала только в pdf.

Вместо ps | grep или pgrep почти всегда использую ps -C, иногда с дополнительным grep: результаты, как правило, содержат меньше мусора. Остальными grepами не пользуюсь; pdfgrep показался полезным, но я о нём просто не слышал.


Также вместо grep -r обычно использую ag, он справляется лучше.

UFO landed and left these words here
или
grep -REho 'regexpr1|regexpr2|...' ./* > fileout
UFO landed and left these words here
Умеет искать в архивах, вложенных друг в друга.

Сразу возникла мысль: как deepgrep обработает рекурсивный архив?
А есть утилита anygrep. которая распознает тип переданного файла/каталога/пакета/etc. и перенаправит запрос одной из утилит, описанных в статье?
ngrep медленно, но все же развивается. Уже на гитхабе.
https://github.com/jpr5/ngrep

Автор вроде тот же — Jordan Ritter. Будем следить.

На днях стояла задача: Вычислить PID определенного процесса. Эксперименты сошлись к двум вызовам:
> pgrep -f process_name
> ps -afx | grep "process_name" | grep -v grep | awk '{print $1}'
Есть утилита pidof
В дебиане входит в пакет sysvinit-utils

для грепа исходников есть няшные ack (пакет ack-grep в дебиане) и ag. Они не лазят во всякие .git, .svn, бинарники и хорошо настроены по дефолту для подсветки итд.

UFO landed and left these words here
exiqgrep — Search in the exim queue

Пример удаления из очереди всех сообщений от определённого отправителя:
exiqgrep -i -f sender@example.com | xargs exim -Mrm
pcre2grep — поиск с «нормальным» (PCRE) синтаксисом регулярных выражений и всякими удобными штуками, вроде вывода отдельных групп из регулярного выражения.

Там, где grep требует экранировать скобки и другие мета-символы (?, +, |) (или не забывать указывать опцию -E), pcre2grep обрабатывает их, как того и ожидаешь в регулярных выражениях:
grep "\(group\)\?" file.txt
и
pcre2grep "(group)?" file.txt

http://www.pcre.org/current/doc/html/pcre2grep.html
Можно egrep вместо grep писать, результат будет тот же. Во многих дистрибутивах просто в grep -E раскрывается, никаких зависимостей не просит.
Да чего уж там, просто используем перл: perl -ne '/(group\S*)/ && print $1,$/;'
Можно и более сложные штуки делать, которые grep не потянет.
UFO landed and left these words here
Only those users with full accounts are able to leave comments. Log in, please.