【问题标题】:Bash (parallel wait execution) [duplicate]Bash(并行等待执行)[重复]
【发布时间】:2017-11-29 01:21:36
【问题描述】:

我有一个主脚本,它从一个文件中读取 5 行,一次执行 5 个不同的 shell 脚本,并等待 5 个完成,然后再开始下一批:

cat file |
while read line1 && read line2  && read line3 && read line4 && read line5 
sh script1.sh &
sh script2.sh &
sh script3.sh &
sh script4.sh &
sh script5.sh &
wait

有没有办法确保即使脚本 {1,3} 完成,一次也始终运行 5 个脚本。即如果 1-5 同时运行并且 1,2 完成。立即开始 6,7。

【问题讨论】:

  • 看看 GNU Parallel 的选项--jobs
  • ...或 GNU 扩展 xargs -P,如果你更喜欢 C 而不是 Perl。
  • @manawa:你在哪里使用变量 line1 到 line5?
  • line{1..5} 被分配为后续架构键的值。即 schema1 = line1 等等....然后我获取这些变量并构建 SQL 输出,稍后我会为每个不同的表执行这些输出。

标签: linux bash


【解决方案1】:

有趣的问题!我能想到的最好方法是保留一个进程的 PID 数组,如果数组中的 PID 少于 5 个,则创建一个新的。像这样的:

while read line1 && read line2  && read line3 && read line4 && read line5 ; do
    sh script1.sh &
    PIDS+=($!)
    sh script2.sh &
    PIDS+=($!)
    sh script3.sh &
    PIDS+=($!)
    sh script4.sh &
    PIDS+=($!)
    sh script5.sh &
    PIDS+=($!)

    for PID in "${PIDS[@]}"; do
        if ! kill -0 "$PID"; then # If the PID is not alive
            if [ ${#PIDS[@]} -lt 5 ]; then
                echo "Process $PID dead, starting new one"
                sh scriptN.sh &
                PIDS+=($!)
            fi
        fi
    done
done

它仍然需要一些工作,但希望这能给你这个想法。如果可以的话,GNU Parrallel 也不会是一个糟糕的选择。

【讨论】:

  • 嘘,嘶嘶声:全大写变量名;请参阅pubs.opengroup.org/onlinepubs/9699919799/basedefs/…,第四段,了解相关的 POSIX 指定的约定。 (全大写名称用于对 shell 和 OS 有意义的变量;具有至少一个小写字符的名称保留给应用程序使用并保证不会发生冲突)。
  • 关于主题的更多信息,请考虑 wait -n(在 bash 4.3 或更高版本中)等待恰好一个进程退出,而无需使用 kill -0 遍历大量它们以找出究竟是哪个就是一个。
  • (另外,这个问题在很大程度上是一个常见问题解答——我们至少每月会收到一次它的新实例)。
  • ...就我个人而言,我非常喜欢 Chepner 在 stackoverflow.com/a/38775799/14122 的回答,使用带有提示式扩展的 wait -n 来检索在线作业的数量。
  • 谢谢,查尔斯!我原以为所有大写变量都是常规的,但你让我明白了。 wait -n 在这里也很有帮助。另外,我没有意识到这是一个常见问题解答——我最近才开始在这里回答问题。感谢您的反馈,干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 2021-10-29
  • 2022-12-18
  • 1970-01-01
  • 2016-09-13
  • 2019-07-25
  • 2016-02-21
相关资源
最近更新 更多