防止子进程(HandbrakeCLI)导致父脚本退出。

8 浏览
0 Comments

防止子进程(HandbrakeCLI)导致父脚本退出。

我有一个批处理转换脚本,可以将各种尺寸的.mkv文件转换为适合ipod/iphone的.mp4文件,并进行裁剪/缩放。确定原始尺寸、所需裁剪和输出文件都正常工作。然而,在第一次转换成功后,HandbrakeCLI会导致父脚本退出。为什么会这样呢?我该如何阻止它?

当前的代码如下:

#!/bin/bash
find . -name "*.mkv" | while read FILE
do
    # 输出文件会是什么?
    DST=../Touch/$(dirname "$FILE")
    MKV=$(basename "$FILE")
    MP4=${MKV%%.mkv}.mp4
    # 如果文件已经存在,则不覆盖
    if [ -e "$DST/$MP4" ]
    then
        echo "不覆盖 $DST/$MP4"
    else
        # 为了简洁起见,删除了确定尺寸/裁剪的内容
        HandbrakeCLI --preset "iPhone & iPod Touch" --vb 900 --crop $crop -i "$FILE" -o "$DST/$MP4" > /dev/null 2>&1
        if [ $? != 0 ]
        then
            echo "$FILE 出现问题" >> errors.log  
        fi
     fi
done

我还尝试了使用trap,但这并没有改变行为(尽管最后一个trap确实触发了)

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

编辑后添加:

“0” trap触发了我对其原因进行了调查。执行bash -x $script发现find | while read循环提前结束。

我将查找和编码重构为单独的脚本。现在,查找循环如下:

find . -name "*.mkv" | while read FILE
do
    handbrake-touch "$FILE"
    if [ $? != 0 ]
    then
        echo "$FILE 出现问题" >> errors.log  
    fi
done

行为仍然相同 - 一个编码后跟着while循环结束。如果我只将“handbrake-touch”替换为“echo $FILE”,所有文件都会被列出。当前目录没有改变(我想知道可能会破坏find | while的原因)。

0
0 Comments

问题:子进程(HandbrakeCLI)导致父脚本退出的原因以及解决方法。

在上述代码中,脚本通过使用管道将文件名传递给HandbrakeCLI命令来处理.mkv文件。然而,由于HandbrakeCLI命令也使用了标准输入(stdin),它可能会读取父脚本的输入,导致父脚本提前退出。

为了解决这个问题,可以通过将一个空字符串(" ")通过管道传递给HandbrakeCLI,来确保它不会使用父脚本的标准输入。这样,即使HandbrakeCLI命令读取了标准输入,也只会读取到空字符串,不会干扰父脚本的执行。

以下是修改后的代码:

find . -name "*.mkv" | while read FILE
do
    echo "" | handbrake-touch "$FILE"
    if [ $? != 0 ]
    then
        echo "$FILE had problems" >> errors.log  
    fi
done

经过修改后,该代码能够正常工作,不会因为子进程HandbrakeCLI的读取操作导致父脚本提前退出。

0