2010-10-28 18 views
6

Tengo el siguiente script bash:script de Bash no salir inmediatamente cuando `exit` se llama

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 

Por alguna razón, se hace eco de launchd message, a la espera de un total de 5 segundos, y luego salir.

¿Por qué ocurre esto y cómo lo hago salir inmediatamente después de que echos launchd message?

Respuesta

9

Dado que está utilizando una tubería, el lazo while se está ejecutando en una subcapa. Ejecútelo en el shell principal en su lugar.

#!/bin/bash 

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

estoy recibiendo un error de sintaxis en la línea de hecho ... – Chetan

+0

Ah, fue porque yo estaba usando/bin/sh, estúpida de mí. – Chetan

+0

Invocar bash as sh deshabilita ciertas funciones, incluida la sustitución de procesos. –

3

Según lo indicado por Ignacio, su tail | while crea una subcategoría. El retraso se debe a que está esperando que se escriba la siguiente línea en el archivo de registro antes de que todo se cierre.

Puede añadir esta línea inmediatamente antes de su comando exit si prefiere no usar la sustitución de proceso:

kill -SIGPIPE $$ 

Por desgracia, no sé de ninguna manera de controlar el código de salida usando este método. Será 141 que es 128 + 13 (el número de señal de SIGPIPE).

Si intenta hacer que el inicio de un daemon dependa de que otro haya comenzado, probablemente exista una forma mejor de hacerlo.

Por cierto, si realmente estás escribiendo un script Bash (que tendría que ser el uso de <() sustitución de proceso), se puede escribir el if así: if [[ $line == *launchd* ]].

2

También puede salir de la subshell con un código de salida revelador y luego probar el valor de "$?" para obtener el mismo efecto que está buscando:

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 
Cuestiones relacionadas