簡體   English   中英

bash:在其stdout中的正則表達式匹配時殺死子進程

[英]bash: kill child process upon regex match in its stdout

我有一個bash腳本,它會生成另一個進程,該進程花費很長時間才能執行,並且經常在不停止的情況下將大量錯誤消息打印到其stdout中。

我想以交互方式讀取其標准輸出,然后在匹配錯誤時立即將其停止。

任何想法如何實現這一點?

例如,在下面的腳本中,我要在其stdout中看到第一個“錯誤”時停止運行的ffmpeg

#!/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輸出:

....
[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分鍾...

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

  1. 在后台運行ffmpeg
  2. $! 捕獲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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM