2012-08-10 21 views
16

Necesito ayuda para enviar la salida (stdin y stdout) de los comandos del sistema a una función bash, mientras sigo aceptando la entrada de argumentos. Algo como el ejemplo que sigue. ¿Puede alguien señalarme por el camino correcto?Redirigir stdout y stderr a la función

LogMsg() 
{ 
    DateTime=`date "+%Y/%m/%d %H:%M:%S"` 
    echo '*****'$DateTime' ('$QMAKESPEC'): '$1 >> "$LogFile" 
    echo $DateTime' ('$QMAKESPEC'): '$1 
} 

# Already works 
LogMsg "This statement is sent directly" 

# Wish I could do this: 
# Capture both stdout & stderr of a system function to the logfile 
# I do not presume that any of the syntax that follows is good 
make 2>&1 >(LogMsg) 
+0

¿Todavía quieres la posibilidad de llamar 'LogMsg' con argumentos de línea de comandos? – chepner

Respuesta

13

para hacer esto, puedes usar la orden interna read bash:

LogMsg() 
{ 
    read IN # This reads a string from stdin and stores it in a variable called IN 
    DateTime=`date "+%Y/%m/%d %H:%M:%S"` 
    echo '*****'$DateTime' ('$QMAKESPEC'): '$IN >> "$LogFile" 
    echo $DateTime' ('$QMAKESPEC'): '$IN 
} 

Y a continuación, utilizar un tubo:

make 2>&1 | LogMsg 

Actualización:

Para poder utilizar la entrada estándar o un argumento como entrada (según el comentario de chepner) se puede hacer esto:

LogMsg() 
{ 
    if [ -n "$1" ] 
    then 
     IN="$1" 
    else 
     read IN # This reads a string from stdin and stores it in a variable called IN 
    fi 

    DateTime=`date "+%Y/%m/%d %H:%M:%S"` 
    echo '*****'$DateTime' ('$QMAKESPEC'): '$IN >> "$LogFile" 
    echo $DateTime' ('$QMAKESPEC'): '$IN 
} 
+2

El único problema con este enfoque es que ya no puede llamar a LogMsg sin probar la entrada estándar. No está claro si Ryan quiere esa flexibilidad. – chepner

+0

@chepner: Buen punto. He actualizado la respuesta en consecuencia. –

+0

Sí, se desea la flexibilidad, debería haber sido más claro. – Ryan

-2

Hay 2 maneras de hacerlo, primera, que creo que es mejor, es la creación de un archivo bash y pasar el resultado de esta manera:

make 2>&1 > ./LogMsg 

la segunda manera es para pasar resultado como un argumento para funcionar:

LogMsg $(make 2>&1) 
+1

Su primera opción no está clara. ¿Quiere pipetear la salida de make a 'LogMsg' (que no puede leer de stdin como está escrito)? Su segunda opción solo procesará la primera línea de make, ya que 'LogMsg' solo procesa su primer argumento. – chepner

-1

En mi opinión, un tiempo de espera de 100 ms (-t 0.1) en el comando de lectura permitirá que el LogMsg maneje la tubería de entrada y los parámetros sin ti t esperando para siempre en caso de no tener entrada.

function log(){ read -t 0.1 IN1 
    echo $(date "+%Y/%m/%d %H:%M:%S")' ('$QMAKESPEC'): '$IN1 $* |tee -a $LogFile ;} 
#test without, with pipe , with pipe and parameters , with parameters only 
log ; echo foo | log ; echo foo | log bar ; log bar 
2015/01/01 16:52:17(): 
2015/01/01 16:52:17(): foo 
2015/01/01 16:52:17(): foo bar 
2015/01/01 16:52:17(): bar 

tee -a duplicados a la salida estándar y lo anexa a $ Archivo_registro

se divierten

Cuestiones relacionadas