首先要说的是,我对 Bash 脚本没有太多经验。
我观察到的问题如下:
当我执行read
命令并在循环内运行后台进程时,该read
命令在极少数情况下会遗漏一些参数。
例如:如果我有大量视频文件read
的输出,并且在每个视频文件上我在不同的子进程中执行命令,那么ls -la
ffmpeg
在极少数情况下,缺少read
命令的一些第一个参数。
在这种情况下,其余参数ls
都是错误的(具有部分真实值或分配错误)。
大多数情况下,我的输出如下(这是正确的):
p1: '-rwxr-x---.'; p2: '1'; p3: 'uman'; p4: 'uman'; p5: '1080519'; p6: 'Jan'; p7: '27'; p8: '05:49'; p9: 'origVideo_453.mp4'
但对于极少数的几行,我没有正确的输出,它是这样的:
p1: 'an'; p2: '1080519'; p3: 'Jan'; p4: '27'; p5: '05:49'; p6: 'origVideo_454.mp4'; p7: ''; p8: ''; p9: ''
这里p1
和p2
缺失了,p3
应该是,"uman"
但只是"an"
。和p3
变成了p1
,p4
变成了p2
,等等,这样p7
,p8
和p9
仍然没有值。
这是我的 bash 脚本:
#!/bin/bash
#src_dir=/tmp/text_files
src_dir=/tmp/video_files
dest_dir=/tmp/video_files_dest
mkdir -p $dest_dir
handle_video() {
echo "handling file: '$1'"
ffmpeg -loglevel error -i $src_dir/$1 -acodec copy -vcodec copy $dest_dir/$1
}
generate_text() {
str=''
for k in {1..512}
do
random=$(openssl rand -hex 20)
str="${str}${random} "
if [ $(( $k % 4 )) -eq 0 ]; then
str="${str} ${new_line}"
fi
done
echo "${str}" > $src_dir/$1
}
while read p1 p2 p3 p4 p5 p6 p7 p8 p9; do
echo "p1: '$p1'; p2: '$p2'; p3: '$p3'; p4: '$p4'; p5: '$p5'; p6: '$p6'; p7: '$p7'; p8: '$p8'; p9: '$p9'"
if test -f $src_dir/$p9; then
handle_video $p9 &
# generate_text $p9 &
fi
done << EOF
$(ls -la $src_dir)
EOF
**当我在同一个线程中而不是在后台运行 `handle_video` 时** 我没有遇到这样的问题(从第 33 行删除 `&`)。
首先,我认为问题可能出在命令 `la -ls` 的输出中,我尝试了其他命令,但我看到了同样的结果 - 在大多数执行中 `read` 具有正确的参数,但在极少数情况下它们是错误的。
我还尝试使用脚本handle_video
(使用ffmpeg
调用)来运行在read
循环内执行的不同函数:generate_text
。
为此,我注释了第 3 行和第 33 行,并取消注释了第 4 行和第 34 行。
有趣的是,使用脚本执行时handle_video
存在问题,但使用脚本执行时generate_text
根本没有这样的问题。至少我在所有测试中都没有发现过这种情况。
使用脚本执行时,handle_video
我将 1200 个视频 .mp4 文件(每个 1.1 MB)放在目录中/tmp/video_files
并运行 bash 脚本。
使用脚本执行时,generate_text
我在目录中生成 1200 个空文件/tmp/text_files
并运行 bash 脚本。
我也尝试过像这样用管道执行read
命令,但结果是一样的:
ls -la $src_dir | while read p1 p2 p3 p4 p5 p6 p7 p8 p9; do
echo "p1: '$p1'; p2: '$p2'; p3: '$p3'; p4: '$p4'; p5: '$p5'; p6: '$p6'; p7: '$p7'; p8: '$p8'; p9: '$p9'"
if test -f $src_dir/$p9; then
handle_video $p9 &
# generate_text $p9 &
fi
done
Bash 版本为:5.2.15(1)-release
ffmpeg 版本 5.0.2
客户机操作系统:Fedora 版本:“36 (工作站版)”
VirtualBox 7.0.2
主机操作系统:Windows 10 版本:21H2
再次,当我不在handle_video
后台运行该函数时(在第 33 行删除 & 符号&
),没有任何问题。
当我再次使用handle_video
该函数时generate_text
,没有任何问题。
所以我想知道方法中是否存在问题read
以及它如何获取参数,或者 bash 如何执行多个进程是否存在问题,或者有什么我不明白的地方。
任何帮助和提示都非常感谢。
以下是实际输出的片段:
p1: '-rwxr-x---.'; p2: '1'; p3: 'uman'; p4: 'uman'; p5: '1080519'; p6: 'Jan'; p7: '27'; p8: '05:49'; p9: 'origVideo_453.mp4'
handling file: 'origVideo_448.mp4'
handling file: 'origVideo_449.mp4'
handling file: 'origVideo_44.mp4'
handling file: 'origVideo_450.mp4'
handling file: 'origVideo_451.mp4'
handling file: 'origVideo_452.mp4'
p1: 'an'; p2: '1080519'; p3: 'Jan'; p4: '27'; p5: '05:49'; p6: 'origVideo_454.mp4'; p7: ''; p8: ''; p9: ''
p1: '-rwxr-x---.'; p2: '1'; p3: 'uman'; p4: 'uman'; p5: '1080519'; p6: 'Jan'; p7: '27'; p8: '05:49'; p9: 'origVideo_455.mp4'
p1: '-rwxr-x---.'; p2: '1'; p3: 'uman'; p4: 'uman'; p5: '1080519'; p6: 'Jan'; p7: '27'; p8: '05:49'; p9: 'origVideo_456.mp4'