我编写了必须将* .avi文件转换为mp4格式的脚本。 然而,“while”循环在第一次迭代后停止。
#!/bin/bash
shopt -s lastpipe
cd <some_directory>
find . -name *.avi -type f |
while read -r avi
do
/usr/bin/HandBrakeCLI -i "${avi}" -o "${avi%.avi}.mp4" -f mp4 -m -O -e x264 -q 20 --vfr \
# &> /dev/null
if [ "$?" -eq 0 ]
then
echo "${avi} was converted successfully"
rm "${avi}"
else
echo "${avi} was not converted"
break
fi
done
答案 0 :(得分:1)
这部分是错误的:find . -name *.avi -type f
shell在 find
启动之前扩展通配符,因此find命令如下所示:
find . -name a.avi b.avi.c.avi d.avi ... -type f
我很惊讶您没有注意到错误消息,例如“find:paths必须先于表达式:b.avi”
您需要保护星号不受外壳影响,因此可以找到自己的扩展名。选择其中一个
find . -name \*.avi -type f
find . -name '*.avi' -type f
你没有提到你是否使用GNU系统。你的while循环有可能被带有前导或尾随空格的文件名绊倒。试试这个:
find . -name \*.avi -type f -print0 | while read -rd '' avi; do ...
答案 1 :(得分:0)
HandBrakeCLI
也可以读取它在第一个实例被调用后使循环结束的输入。由于您正在使用bash,因此您可以将重定向输入的进程替换用于另一个文件描述符。在此示例中使用4
:
while read -ru 4 avi; do
...
done 4< <(exec find . -name *.avi -type f)
我的首选版本也是使用readarray
。如果你没有针对他们有换行符的不规则文件名,那就足够了:
readarray -t files < <(exec find . -name *.avi -type f)
for avi in "${files[@]}"; do
...
done
另一种方法可能是将HandBrakeCLI
的输入重定向到/dev/null
:
</dev/null /usr/bin/HandBrakeCLI ...
其他建议:
-name
模式:'*.avi'
IFS=
来防止删除前导和尾随空格:IFS= while read ...