2010-10-28 3 views
6

Ho il seguente script bash:script Bash non uscendo immediatamente quando `exit` viene chiamato

tail -F -n0 /private/var/log/system.log | while read line 
do 
    if [ ! `echo $line | grep -c 'launchd'` -eq 0 ]; then 
     echo 'launchd message' 
     exit 0 
    fi 
done 

Per qualche ragione, è eco launchd message, in attesa di un pieno di 5 secondi, e poi uscire.

Perché sta succedendo questo evento e come faccio a uscire immediatamente dopo echos launchd message?

risposta

9

Poiché si sta utilizzando una pipe, il ciclo while viene eseguito in una subshell. Eseguilo invece nella shell principale.

#!/bin/bash 

while ... 
do 
    ... 
done < <(tail ...) 
+0

sto ottenendo un errore di sintassi alla linea di fatto ... – Chetan

+0

Ah, era perché stavo usando/bin/sh, stupido me. – Chetan

+0

Invocare bash come sh disabilita alcune funzionalità, inclusa la sostituzione del processo. –

3

Come indicato da Ignacio, lo tail | while crea una subshell. Il ritardo è dovuto al fatto che è in attesa che la riga successiva venga scritta nel file di registro prima che tutto si chiuda.

È possibile aggiungere immediatamente questa linea prima il vostro comando exit se si preferisce non usare la sostituzione di processo:

kill -SIGPIPE $$ 

Purtroppo, non so di un modo per controllare il codice di uscita utilizzando questo metodo. Sarà 141, ovvero 128 + 13 (il numero di segnale di SIGPIPE).

Se stai provando a rendere l'avvio di un demone dipendente da un altro avviato, probabilmente c'è un modo migliore per farlo.

A proposito, se siete veramente scrivendo uno script Bash (che avrebbe dovuto essere quello di utilizzare <() sostituzione di processo), è possibile scrivere il if in questo modo: if [[ $line == *launchd* ]].

2

È anche possibile uscire dalla sottochiave con un codice di uscita della spia e quindi verificare il valore di "$?" per ottenere lo stesso effetto che stai cercando:

tail -F -n0 /private/var/log/system.log | while read line 
do 
    if [ ! `echo $line | grep -c 'launchd'` -eq 0 ]; then 
     echo 'launchd message' 
     exit 10 
    fi 
done 
if [ $? -eq 10 ]; then exit 0; fi