2012-08-10 25 views
16

Potrzebuję pomocy przy wysyłaniu danych wyjściowych (stdin i stdout) z poleceń systemowych do funkcji basha, nadal akceptując dane wejściowe z argumentów. Coś jak poniższy przykład. Czy ktoś może wskazać mi właściwą drogę?Przekierowanie stdout i stderr do funkcji

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

Czy nadal chcesz możliwość wywoływania 'LogMsg' z argumentami wiersza polecenia? – chepner

Odpowiedz

13

aby to zrobić, można użyć polecenie wbudowane 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 
} 

a następnie użyć rury:

make 2>&1 | LogMsg 

Aktualizacja:

Aby móc korzystać z stdin lub argumentu jako wejścia (jak na komentarz chepner za) można to zrobić:

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

Jedynym problemem z tym podejściem jest to, że nie można już wywoływać LogMsg bez udowodnienia standardowego wejścia. Nie jest jasne, czy Ryan chce takiej elastyczności. – chepner

+0

@chepner: Dobra uwaga. Odpowiednio zaktualizowałem odpowiedź. –

+0

Tak, elastyczność jest pożądana, powinienem być bardziej przejrzysty. – Ryan

-2

Istnieją 2 sposoby robienia tak, pierwsze, co moim zdaniem jest lepszy, jest stworzenie pliku bash i przekazać wynik do niego tak:

make 2>&1 > ./LogMsg 

drugi sposób jest przekazać prowadzić jako argument funkcjonować:

LogMsg $(make 2>&1) 
+1

Twoja pierwsza opcja jest niejasna. Czy chcesz wyprowadzić wyjście make do 'LogMsg' (którego nie można odczytać ze standardowego wejścia)? Twoja druga opcja przetworzy tylko pierwszą linię z make, ponieważ 'LogMsg' przetwarza tylko pierwszy argument. – chepner

-1

Moim zdaniem, limit czasu wynoszący 100ms (-t 0.1) w poleceniu odczytu pozwoli LogMsg na obsługę wejściowych rurociągów i parametrów bez t czekanie na zawsze w przypadku braku danych wejściowych.

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 duplikaty do stdout i dołącza do $ LogFile

baw

Powiązane problemy