2014-01-14 48 views
0

我有一個bash腳本,它產生了需要很長時間才能執行的另一個進程,並且經常在不停止的情況下將大量錯誤消息輸出到它的stdout。bash:在其標準輸出正則表達式匹配時終止子進程

我想交互式地閱讀它的stdout,然後在匹配錯誤時立即停止它。

任何想法如何實現?

例如,在下面的腳本,我想在看到第一個「錯誤」,在標準輸出

 
#!/bin/bash 

FFMPEG="/usr/bin/ffmpeg" 
LIST=`find | grep \..` 

for i in $LIST; do 
    OUTP="$i.txt" 
    OUTP_OK="$i.txt.ok" 
    TMP_OUTP="$i.tmp" 
    if [ -f "$OUTP" -o -f "$OUTP_OK" ] ; then 
    echo Skipping "$i" 
    else 
    echo Checking "$i"... 
    RESULT="bad" 
    echo "$FFMPEG" -v 5 -i "$i" -f null - 2> "$TMP_OUTP" 
    "$FFMPEG" -v 5 -i "$i" -f null - 2> "$TMP_OUTP" && \ 
     mv "$TMP_OUTP" "$OUTP" && \ 
     RESULT=`grep -v "\(frame\)\|\(Press\)" "$OUTP" | grep "\["` 
    if [ -z "$RESULT" ] ; then 
     mv "$OUTP" "$OUTP_OK" 
    fi 
    fi 
done 

ffmpeg的輸出,以停止正在運行的ffmpeg:

 
.... 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
[eac3 @ 0x144a420] frame CRC mismatch 
Input stream #0:0 frame changed from rate:48000 fmt:s16 ch:6 to rate:16000 fmt:s16 ch:2 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
Input stream #0:0 frame changed from rate:16000 fmt:s16 ch:2 to rate:48000 fmt:s16 ch:6 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
[eac3 @ 0x144a420] frame CRC mismatch 
Input stream #0:0 frame changed from rate:48000 fmt:s16 ch:6 to rate:48000 fmt:s16 ch:2 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
Input stream #0:0 frame changed from rate:48000 fmt:s16 ch:2 to rate:48000 fmt:s16 ch:6 
[eac3 @ 0x144a420] frame sync error 
Error while decoding stream #0:0 
... 

...和上上,並持續20分鐘...

回答

0

修補其他一些堆棧溢出帖子在一起,你會:

  1. 在後臺
  2. 使用$!運行FFMPEG捕捉ffmpeg的PID
  3. 使用grep -q阻塞,直到它找到的正則表達式,其任選被一個超時因此它不會永遠阻塞
  4. 殺PID時正則表達式被找到。

事情是這樣的:

#Run ffmpeg in the background, saving its process id with `S!` 
"$FFMPEG" -v 5 -i "$i" -f null - 2> "$TMP_OUTP" && 
FFMPEG_ID=$! 
#use "grep -q" to block waiting for regex in TMP_OUTP 
#See http://stackoverflow.com/questions/6454915/linux-block-until-a-string-is-matched-in-a-file-tail-grep-with-blocking 
timeout 3600 grep -q 'error' <(tail -f $TMP_OUTP) 
#We timed out or found the value, kill the process 
kill -9 $FFMPEG_ID 
+0

任何方式使用grep沒有超時(因爲ffmpeg的執行時間是未知的)?還要將匹配狀態捕獲到主腳本中? (即在輸出中找到錯誤,或者在沒有發現錯誤的情況下退出ffmpeg) – user3192647

+0

當然,您可以使用grep w/out超時。 'timeout'只是一個超時運行命令的工具 - 參見'man timeout'如果你想捕獲匹配狀態,使用'grep -m 1 error'而不是'grep -q error',它告訴grep退出之後它匹配「錯誤」一次。請注意,如果沒有超時,tail -f會在ffmpeg退出後無限期地拖尾文件,除非ffmpeg在退出時會在輸出中放入可與grep匹配的內容。 – lreeder