Bash 中的“读取”命令是否存在问题,或者使用多处理时 Bash 本身是否存在问题,或者我可能犯了一些错误?

Bash 中的“读取”命令是否存在问题,或者使用多处理时 Bash 本身是否存在问题,或者我可能犯了一些错误?

首先要说的是,我对 Bash 脚本没有太多经验。
我观察到的问题如下:

当我执行read命令并在循环内运行后台进程时,该read命令在极少数情况下会遗漏一些参数。

例如:如果我有大量视频文件read的输出,并且在每个视频文件上我在不同的子进程中执行命令,那么ls -laffmpeg在极少数情况下,缺少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: ''

这里p1p2缺失了,p3应该是,"uman"但只是"an"。和p3变成了p1p4变成了p2,等等,这样p7p8p9仍然没有值。

这是我的 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'

相关内容