2012-01-22 10 views
23

Perché la seguente istruzione if ha esito positivo?

if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi 
+4

Se la tua corsa 'ps aux | grep "bla bla" 'vedrai perché ... –

+0

Vedi anche [questa domanda] (http://stackoverflow.com/questions/8965887/command-substitution-in-if-statement-condition). –

+3

'se pgrep -f" bla bla "; quindi echo "trovato"; fi' – jordanm

risposta

32

Poiché il processo grep stessa viene restituito da ps. È possibile "trucco" grep di non corrispondere stesso circondando uno dei personaggi di ricerca in una classe di caratteri [ ] che non cambia la funzionalità: Basta fare:

if ps aux | grep -q "[b]la bla" ; then echo "found" ; fi 

Inoltre, l'uso di sostituzione di processo è $() non necessario. Il if funzionerà sul successo dell'ultimo comando nella catena di condotte, che è ciò che si desidera.

Nota: La ragione per cui il trucco classe di personaggio funziona è perché l'uscita ps ha ancora le staffe di classe del personaggio, ma quando grep sta elaborando la stringa di ricerca, utilizza le staffe come sintassi piuttosto che una stringa fissa da abbinare.

+0

go go gadget downvoter – SiegeX

+0

C'è un downvoter seriale là fuori: P –

+0

Bel trucco! Grazie! –

7

il processo "grep" è già in esecuzione al momento dell'esecuzione di ps, quindi l'output ps lo include.

Provare a utilizzare pgrep invece.

pgrep è proprio per questo scopo:

if pgrep "bla bla" ; then echo "found" ; fi

+0

Mr Downvoter, ho modificato la mia risposta per maggiore chiarezza. Si prega di vedere se ora sembra migliore. Ta – laher

1

è necessario filtrare il processo che è grep ping per 'bla bla':

$ if ps aux | grep -v 'grep' | grep -q 'bla bla'; then 
    echo 'Found' 
fi 
+0

non vuoi il -v grep dopo il grep di destinazione? (Se downvot, dico perché). – shellter

+0

Ho anche downvoted due volte senza alcuna spiegazione. Penso che qualcuno stia scrivendo molto liberamente su questa domanda ... – laher

+0

@ amir75: sembra che tutti i downvotes siano scomparsi (ancora senza spiegazione!) ;-) Buona fortuna a tutti. – shellter

8

Se grep l'output ps aux, verrà sempre visualizzato un processo che mostra il comando precedente. Per risolvere questo problema, puoi reindirizzare l'output a grep due volte, una volta per rimuovere la riga con "grep", e ancora per il processo che stai cercando.

 
ps aux | grep -v "grep" | grep "Finder" 
2

Il $( è un piccolo po 'rilevanti, e cambia il significato un po'. Anche se in questo caso, poiché non viene mai prodotto alcun output da grep -q, è possibile ottenere semplicemente lo $(. Probabilmente si vuole iniziare con qualcosa di simile (come sottolineato da altri):

if ps aux | grep -v 'grep' | grep -q 'bla bla'; then 
    echo 'Found' 
fi 

In ogni caso, si è iniziato con

if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi 

Con $(, il comando all'interno del $() viene eseguita e l'uscita di quel il comando è usato come riga di comando per il comando esterno.Fare questi quattro esperimenti:

# if $(echo nonexistant ; true) ; then echo "found" ; fi 
nonexistant: command not found 

# if $(echo nonexistant ; false) ; then echo "found" ; fi 
nonexistant: command not found 

# if $(echo ; true) ; then echo "found" ; fi 
found 

# if $(echo ; false) ; then echo "found" ; fi 

Quindi, in base a questo si emette ottenere found se entrambe queste condizioni:

  • Il comando all'interno del $() creato
  • e il comando no uscita ha avuto successo

Ciò suggerisce che ps aux | grep -q "bla bla" ha avuto successo e non ha creato output. Non sorprende che lo grep -q non crei output. Questo è ciò che il -q è per. Pertanto, il tuo comando deve avere uno stato vero, il che implica che il grep ha trovato una corrispondenza. Sappiamo che grep troverà sempre una corrispondenza in questo caso, perché l'elenco dei processi da ps includerà lo stesso grep; il grep troverà sempre se stesso.

+0

bella spiegazione "esplosa" di ciò che sta accadendo. – shellter

Problemi correlati