Vraag Hoe te voorkomen dat "ps" zijn eigen proces rapporteert?


$ 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

Is er een manier om te voorkomen dat het laatste proces (dat wil zeggen, de grep die op hetzelfde moment werd gestart als mijn ps-opdracht) werd gerapporteerd?

(Ik begon te proberen een regex te bedenken die overeenkwam met de letterlijke maar niet de match zelf, maar dat leek niet de juiste aanpak ...)


49
2018-03-09 05:42


oorsprong




antwoorden:


Mijn antwoord is een variatie op het typische antwoord voor het zoeken naar "foobar" in a ps lijst. Het argument van "-A" "ps" is draaglijker dan "aux", Geloof ik, maar deze verandering is niet relevant voor het antwoord. Het typische antwoord ziet er als volgt uit:

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

In plaats daarvan gebruik ik dit patroon:

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

Het grote voordeel is dat het gemakkelijker is om scripts te schrijven op basis van dit patroon, omdat u eenvoudig een statische tekenreeks aaneenschakelt [^]] met welk patroon je ook zoekt. U hoeft de eerste letter van de string niet af te trekken en vervolgens tussen de vierkante accolades te plaatsen en vervolgens die weer samen te voegen. Bij scripting in shell is het eenvoudiger om eenvoudig te plakken [^]] voor het patroon waar je naar op zoek was. String slicing in Bash is een lelijk iets, dus mijn variatie vermijdt dat. Deze variatie geeft de lijnen weer waar het patroon overeenkomt ZONDER een leidende vierkante rechts-haakje]. Omdat het zoekpatroon om een ​​vierkante haak uit te sluiten, de vierkante haakjes daadwerkelijk aan het patroon toevoegt, zal deze nooit zichzelf evenaren.

Dus je zou een draagbare computer kunnen schrijven psgrep commando als volgt. Hier houd ik rekening met verschillen tussen Linux, OS X BSD en andere. Hiermee worden de kolomkoppen toegevoegd ps, biedt een meer aangepaste ps formaat dat geschikt is voor mijn behoeften, en toont processen die extra, extra breed weergeven, zodat geen van de opdrachtregelargumenten over het hoofd wordt gezien. Nou, de meeste worden niet gemist. Java is Java, het doet de dingen vaak op de slechtst mogelijke manier, dus zullen sommige java-services voorbij de maximaal toegestane lengte van argumenten gaan die de procestabel bijhoudt. Ik geloof dat dit 1024 karakters zijn. De opdracht-een-lengte die is toegestaan ​​om een ​​proces te starten is veel langer, maar de kernel-procestabel neemt niet de moeite om iets van meer dan 1K in de lengte bij te houden. Nadat de opdracht is gestart, is de opdrachtnaam en argumentlijst niet nodig, dus wat in de procestabel wordt opgeslagen, is slechts informatief.

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
}

12
2018-03-05 01:49



Nadeel is dat dit feitelijk één char meer (vooraan) zal matchen dan het originele patroon. Dit komt bijvoorbeeld nooit overeen met de PID. En kan bij gebruik een beetje misleidend zijn grep --colour. - Tonin


+1 voor @jamzed kort antwoord, maar misschien heeft het OP enige uitleg nodig:

ps | grep "[d]jango"

Met die regex start je een proces waarvan de ps-string zichzelf niet evenaart, omdat de regexp overeenkomt "django" en niet "[d]jango". Op die manier sluit je het proces uit met de string "[d] jango" die in dit geval grep is; Hetzelfde kan worden toegepast op pgrep, egrep, awk, sed, etc ... welk commando je ook hebt gebruikt om de regex te definiëren.

Van man 7 regex

   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.

65
2018-03-09 07:54



Stoer. Ik ben eigenlijk behoorlijk comfortabel met regexs, maar kon niet meteen een manier bedenken om te voorkomen dat de regexp zelf zou matchen. Het is logisch om een ​​letter tussen vierkante haken bij te voegen. (Inclusief zoiets als [^!] Zou ook werken ...) - Steve Bennett
Dat is leuk en sluw. - ash
Voor het geval 'ps' gebruik ik '[]' aan de voorkant van de procesnaam waarnaar ik op zoek ben. Dan hoef ik de procesnaam niet speciaal voor de regex te ontleden, maar deze komt nog steeds overeen. - Neromancer
@hmontoliu Het werkt bijvoorbeeld niet: ps aux | grep [s]cript1. Zou je kunnen helpen commentaar te geven over de oplossing? - SOUser
@hmontoliu Mijn schuld. Het lijkt erop dat de lijn wordt weergegeven vanwege eerdere zoekopdrachten ... - SOUser


ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


29
2018-03-09 07:10



Voeg ruimte toe als u één teken wilt grepen: ps aux| grep "[Z] " - A.D.
@jamzed Het werkt bijvoorbeeld niet: ps aux | grep [s]cript1 of ps aux | grep [s]cript2. De grep-regel wordt nog steeds weergegeven. Zou je kunnen helpen commentaar te geven over de oplossing? - SOUser
@jamzed Mijn schuld. Het lijkt erop dat de lijn wordt weergegeven vanwege eerdere zoekopdrachten ... - SOUser


Gebruik in plaats daarvan pgrep: pgrep -lf django


17
2018-03-09 06:19



Zoals gewoonlijk vergat ik het platform te vermelden (OS X in dit geval). Waarschijnlijk werkt pgrep op verschillende linuxes. - Steve Bennett
Ik ben het er niet mee eens, @ramruma. Ik kwam precies op deze draad omdat pgrepgeeft me precies dit probleem. Maar ik moet zeggen dat ik het in CygWin test (waar ps kan de volledige commandolijn van het proces niet weergeven). - Sopalajo de Arrierez
In de handleiding staat: "Het lopende pgrep- of pkill-proces zal zichzelf nooit als een match melden", en ik heb het inderdaad niet gezien. - deltab


Oh wacht, dit werkt:

ps | grep django | grep -v grep

11
2018-03-09 05:46



Alleen als de procesopdrachtregel niet legitiem is grep, waar u in het algemene geval niet op kunt rekenen. - α CVn


ps -d | grep django

van man ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

8
2017-10-23 14:08



laat grep nog steeds zien van mij ... - Kevin
Ja, dat werkt voor mij op OS X. - Steve Bennett
Werkt niet zo goed op Linux. - A-B-B
Meer in het algemeen, de opties om ps zijn notoir niet-draagbaar, dus zonder informatie over op welk platform dit is, is dit antwoord niet erg nuttig. Bovendien is dit duidelijk niet voldoende als je niet zeker weet of het proces waarnaar je op zoek bent geen procesleider is (dat wil zeggen, dit kan helpen als je doelwit een daemon is, maar meestal niet anders). - tripleee