Jak zapobiec zgłaszaniu własnego procesu przez „ps”?

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

Czy istnieje sposób, aby zapobiec zgłoszeniu ostatniego procesu (tj. Grep, który został uruchomiony w tym samym czasie, co polecenie ps)?

(Zacząłem wymyślać wyrażenie regularne, które pasowałoby do literału, ale nie pasowało do samego siebie, ale wydawało się, że, hm, niewłaściwe podejście ...

Steve Bennett
źródło

Odpowiedzi:

14

Moja odpowiedź jest odmianą typowej odpowiedzi dotyczącej wyszukiwania „foobar” na psliście. Argument "-A" "ps"jest bardziej przenośny niż "aux", jak sądzę, ale ta zmiana nie ma znaczenia dla odpowiedzi. Typowa odpowiedź wygląda następująco:

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

Zamiast tego używam tego wzoru:

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

Główną zaletą jest to, że łatwiej jest pisać skrypty oparte na tych wzorcach, ponieważ po prostu łączy się ciąg statyczny [^]]z dowolnym szukanym wzorcem. Nie musisz zdejmować pierwszej litery sznurka, a następnie wstawiać go między kwadratowe nawiasy klamrowe, a następnie ponownie łączyć je z powrotem. Podczas pisania skryptów w powłoce łatwiej jest po prostu trzymać [^]]się wzoru, którego szukałeś. Przecinanie strun w Bash jest brzydką rzeczą, więc moja odmiana tego unika. Ta odmiana mówi, że pokaż linie, w których wzór pasuje BEZ wiodącego prawego nawiasu kwadratowego]. Ponieważ wzorzec wyszukiwania wykluczający nawias kwadratowy faktycznie dodaje nawias kwadratowy do wzorca, nigdy nie będzie pasował do siebie.

Możesz więc napisać przenośne psgreppolecenie w następujący sposób. Tutaj uwzględniam różnice między Linuksem, OS X BSD i innymi. To dodaje nagłówki kolumn z ps, zapewnia bardziej niestandardowepsFormat, który lepiej odpowiada moim potrzebom, wyświetla lepiej procesy i wyświetla listę wyjątkowo, bardzo szeroką, aby żaden z argumentów wiersza poleceń nie został pominięty. Cóż, większość nie jest pominięta. Java, która jest Javą, często robi wszystko w najgorszy możliwy sposób, więc niektóre usługi java będą działać po przekroczeniu maksymalnej dozwolonej długości argumentów, które śledzi tabela procesów. Myślę, że to 1024 znaki. Długość pojedynczego polecenia pozwalająca na uruchomienie procesu jest znacznie dłuższa, ale tabela procesów jądra nie zadaje sobie trudu, aby śledzić wszystko o długości przekraczającej 1 K. Po uruchomieniu polecenia nazwa-polecenia i lista argumentów nie są potrzebne, więc to, co jest przechowywane w tabeli procesów, ma jedynie charakter informacyjny.

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
}
Noah Spurrier
źródło
Wadą jest to, że w rzeczywistości będzie pasował o jeden znak więcej (z przodu) niż oryginalny wzór. Na przykład, to nigdy nie będzie pasować do PID. I może być nieco mylące, gdy jest używany z grep --colour.
Tonin,
67

+1 za zwięzłą, zwięzłą odpowiedź, jednak OP może wymagać wyjaśnienia:

ps | grep "[d]jango"

Za pomocą tego wyrażenia regularnego uruchamiasz proces, którego ciąg ps nie będzie pasował do siebie, ponieważ wyrażenie regularne pasuje, "django"a nie "[d]jango". W ten sposób wykluczysz proces zawierający ciąg „[d] jango”, którym w tym przypadku jest grep; To samo można zastosować do pgrep, egrep, awk, sed itp., Niezależnie od polecenia użytego do zdefiniowania wyrażenia regularnego.

Od człowieka 7 wyrażenia regularnego

   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
źródło
2
Chłodny. Właściwie jestem całkiem nieźle z wyrażeniami regularnymi, ale nie mogłem od razu wymyślić sposobu, aby zapobiec dopasowaniu wyrażeń regularnych. Zawarcie litery w nawiasach kwadratowych ma sens. (W tym coś takiego jak [^!] Też by działało ...)
Steve Bennett
1
To miło i podstępnie.
popiół
W przypadku szczególnym „ps” używam „[]” na początku szukanej nazwy procesu. Następnie nie muszę analizować nazwy procesu specjalnie dla wyrażenia regularnego, ale nadal pasuje.
Neromancer
@hmontoliu To nie działa na przykład: ps aux | grep [s]cript1. Czy mógłbyś pomóc w komentowaniu rozwiązania?
SOUser
@hmontoliu Moja wina. Wygląda na to, że wiersz został wyświetlony z powodu poprzednich wyszukiwań ...
SOUser,
30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]

zakleszczony
źródło
Dodaj miejsce, jeśli chcesz grepować jeden znak:ps aux| grep "[Z] "
AD
@jamzed To nie działa na przykład: ps aux | grep [s]cript1lub ps aux | grep [s]cript2. Linia grep jest nadal wyświetlana. Czy mógłbyś pomóc w komentowaniu rozwiązania?
SOUser
@jamzed Moja wina. Wygląda na to, że wiersz został wyświetlony z powodu poprzednich wyszukiwań ...
SOUser,
18

Zamiast tego użyj pgrep: pgrep -lf django

ramruma
źródło
Jak zwykle zapomniałem wspomnieć o platformie (w tym przypadku OS X). Prawdopodobnie pgrep działa na różnych linuksach.
Steve Bennett,
Nie zgadzam się, @ramruma. Doszedłem do tego wątku właśnie dlatego, że pgrepdaje mi dokładnie ten problem. Ale muszę powiedzieć, że testuję to w CygWin (gdzie psnie można wyświetlić pełnej linii poleceń procesu).
Sopalajo de Arrierez
Instrukcja mówi: „Uruchomiony proces pgrep lub pkill nigdy nie zgłasza się jako dopasowanie.”, I rzeczywiście nie widziałem, żeby to robiło.
deltab
Właśnie miałem do czynienia z problemem, który moim zdaniem pgreppasował do siebie. Okazuje się, że pasował do nazwy bashpliku skryptu, z którego go uruchomiłem. Dodanie -xgo naprawiło, a następnie dokładnie pasuje do nazwy polecenia.
andynormancx
11

Och, czekaj, to działa:

ps | grep django | grep -v grep
Steve Bennett
źródło
7
Tylko jeśli wiersz polecenia procesu nie zawiera zgodnego z prawem uzasadnienia grep, na co nie można liczyć w ogólnym przypadku.
CVn
8

ps -d | grep django

od człowieka ps:

 -d                  Lists information  about  all  processes
                     except session leaders.
bla
źródło
nadal pokazuje grep na mojej ...
Kevin
Tak, to działa dla mnie na OS X.
Steve Bennett
Nie działa tak dobrze w systemie Linux.
Acumenus,
Mówiąc bardziej ogólnie, opcje psbycia notorycznie nieprzenośnymi, więc bez informacji o tym, dla której platformy to jest, ta odpowiedź nie jest bardzo pomocna. Co więcej, nie jest to oczywiście odpowiednie, gdy nie masz pewności, że proces, którego szukasz, nie jest liderem procesu (tzn. Może to pomóc, jeśli twoim celem jest demon, ale ogólnie nie inaczej).
tripleee
Zabawne, na Macu wydaje się, że pokazuje to tylko proces grep i odfiltrowuje wszystko inne.
Christopher Hunter,