Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

bash - Preventing a child process (HandbrakeCLI) from causing the parent script to exit

I have a batch conversion script to turn .mkvs of various dimensions into ipod/iphone sized .mp4s, cropping/scaling to suit. Determining the original dimensions, required crop, output file is all working fine. However, on successful completion of the first conversion, HandbrakeCLI causes the parent script to exit. Why would this be? And how can I stop it?

The code, as it currently stands:

#!/bin/bash
find . -name "*.mkv" | while read FILE
do
    # What would the output file be?
    DST=../Touch/$(dirname "$FILE")
    MKV=$(basename "$FILE")
    MP4=${MKV%%.mkv}.mp4

    # If it already exists, don't overwrite it
    if [ -e "$DST/$MP4" ]
    then
        echo "NOT overwriting $DST/$MP4"
    else

        # Stuff to determine dimensions/cropping removed for brevity

        HandbrakeCLI --preset "iPhone & iPod Touch" --vb 900 --crop $crop -i "$FILE" -o "$DST/$MP4" > /dev/null 2>&1

        if [ $? != 0 ]
        then
            echo "$FILE had problems" >> errors.log  
        fi
     fi
done

I have additionally tried it with a trap, but that didn't change the behaviour (although the last trap did fire)

trap "echo Handbrake SIGINT-d"  SIGINT
trap "echo Handbrake SIGTERM-d" SIGTERM
trap "echo Handbrake EXIT-d"    EXIT
trap "echo Handbrake 0-d"       0

Edited to add:

The fact that the '0' trap fired prompted me to investigate why that might be. Executing as bash -x $script revealed that the find | while read loop is ending prematurely.

I've re-factored the find and encode into separate scripts. The find loop is now:

find . -name "*.mkv" | while read FILE
do
    handbrake-touch "$FILE"

    if [ $? != 0 ]
    then
        echo "$FILE had problems" >> errors.log  
    fi
done

The behaviour remains the same - one encode followed by the while loop ending. If I just put an 'echo $FILE' in place of the 'handbrake-touch', all the files are listed. The current directory doesn't change (I was wondering what might break the find | while).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Now resolved, thanks to a clue from this other thread. I now echo nothing into HandbrakeCLI to ensure it's not using the same stdin as my script:

find . -name "*.mkv" | while read FILE
do
    echo "" | handbrake-touch "$FILE"

    if [ $? != 0 ]
    then
        echo "$FILE had problems" >> errors.log  
    fi
done

...and it works as intended/expected.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...