防止子进程(HandbrakeCLI)导致父脚本退出。
防止子进程(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
的原因)。
问题:子进程(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的读取操作导致父脚本提前退出。