【问题标题】:Distributing lines of commands using bash script使用 bash 脚本分发命令行
【发布时间】:2012-07-19 08:11:13
【问题描述】:

我正在尝试实现简单的并行化,其中命令行分布在不同的进程中。为此,我编写了这个脚本,我将其命名为 jobsel:

(only "#! /bin/bash" and help message is omitted)

slots=$1
sel=$2

[[ $slots -gt 0 ]] || die_usage
[[ $sel -lt $slots ]] || die_usage

i=0
while read line
do
        (( i % slots == sel )) && eval $line
        i=$(( i + 1 ))
done

# in case the last line does not end with EOL
if [[ $line != "" ]]; then
        (( i % slots == sel )) && eval $line
        i=$(( i + 1 ))
fi

我输入了eval,因为没有它我无法在命令中使用重定向或管道。

当我在控制台模拟器上像$HOME/util/jobsel 22 0 < cmds 一样运行它时,当cmds 是一个包含echo 0 >> out 之类的行且数量不断增加的文件时,它会按预期在单独的行中输出0, 22, 44...。到目前为止还不错。

所以我把它付诸实践。但是当我通过安全 shell 运行它时,我通过带有背景的at 运行它(每行以& 结束)。然后有一个问题。当我输入 8 行时,启动了 21 个进程! ps -AFH 打印具有相同命令和不同 pID 的进程。所有工作流程都在同一级别,直接在 init 之下。我的程序无论如何都不会创建子进程。

困惑,我通过at 尝试了echo 0 >> out 脚本,然后输出包含重复的行。仍然难以相信,并认为同时追加可能导致异常,我使用其他方法确认某些行运行了多次。

此外,当一切都在终端中运行或我为每个工作进程创建单独的at 作业时,没有这种异常情况。

但这怎么会发生呢?我的脚本有问题吗? at/atd 有问题吗?

【问题讨论】:

  • 代替[[ $(( i % slots )) -eq $sel ]] 做(( i % slots == sel ))。请参阅Process Management 和BashFAQ/050。
  • 你考虑过使用GNU parallel吗?
  • @DennisWilliamson 谢谢。我正在申请编辑。
  • at 在省略最终的& 时似乎表现良好。但情况并非总是如此。所以我转向nohups。
  • 另外,((slots > 0 )) 和 ((sel < slots ))

标签: bash process parallel-processing


【解决方案1】:

GNU parallel 是您尝试实现的。

提示:结合 xargs 效果很好

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2014-06-28
    • 2021-11-17
    • 2015-01-09
    • 2017-01-04
    • 2018-08-19
    相关资源
    最近更新 更多