【问题标题】:bash: manager processes runbash:管理器进程运行
【发布时间】:2018-08-02 03:46:27
【问题描述】:

我在 $tmpdir/$i.dirlist 中有多个文件,其中包含条目命令 rsync。 每个文件有(取决于数量)10 有时 50 甚至 150 个 rsync 条目。

我现在想知道如何通过带有 IF 序列的 FOR 或 WHILE 循环来管理它,以便从每个文件($tmpdir/$i.dirlist - 如果我们有 100 个文件)只有 2 个条目并等待完成一些进程如果 rsync 的所有运行进程总数少于 200 个进程 - 启动新条目,保持参数中定义的固定进程数。在这种情况下 200

有什么想法吗?怎么办?

编辑: 关于 rsync 条目。 在每个文件中 $tmpdir/*.dirlist 是(在本例中为 200)目录条目

路径如下:

==> /tmp/rsync.23611/0.dirlist <==
system/root/etc/ssl
system/root/etc/dbus-1
system/root/etc/lirc
system/root/etc/sysctl.d

==> /tmp/rsync.23611/1.dirlist <==
system/root/etc/binfmt.d
system/root/etc/cit
system/root/etc/gdb

==> /tmp/rsync.23611/2.dirlist <==
system/root/usr/local
system/root/usr/bin
system/root/usr/lib

现在运行它我只是为了

for i in $(seq 1 $rsyncs); do
    while read r; do 
        rsync $rsyncopts backup@$host:$remotepath/$ri $r 2>&1 | 
            tee $tmpdir/$i.dirlist.log ; 
    done < $tmpdir/$i.dirlist &
done

【问题讨论】:

  • 如果我理解正确,您有一个要从文件 $tmpdir/*.dirlist 执行的命令列表,并且您希望为每个 .dirlist 同时执行 2 个命令文件。我假设每次流程完成时,您都想开始另一个流程。
  • 你试过什么?您能否提供任何示例(甚至缩短,因为 150 个条目太多了)?
  • 你能解释一下你所说的 rsync 条目是什么意思吗?它是调用 rsync 的 bash 命令行吗?
  • 是的,先生们,我想做的正是它所描述的@PierreFrançois
  • 关于rsync入口。我编辑了帖子/问题,因为消息太长,无法发表评论:)

标签: bash shell for-loop while-loop


【解决方案1】:

假设 $i 的最大值为 100,而您上面的代码仍然低于您希望允许的 200 个进程的最大值。

因此,解决方案是运行两倍的进程。我建议您将主循环 for i in $(seq 1 $rsyncs); do ... 分成两个同时运行的循环,由 resp 引入。 for i in $(seq 1 2 $rsyncs); do ... 用于$i 的奇数值,for i in $(seq 2 2 $rsyncs); do ... 用于$i 的偶数值。

for i in $(seq 1 2 $rsyncs); do         # i = 1 3 5 ...
    while read r; do 
        rsync $rsyncopts backup@$host:$remotepath/$ri $r 2>&1 | 
            tee $tmpdir/$i.dirlist.log ; 
    done < $tmpdir/$i.dirlist &
done &                                  # added an ampersand here
for i in $(seq 2 2 $rsyncs); do         # i = 2 4 6 ...
    while read r; do 
        rsync $rsyncopts backup@$host:$remotepath/$ri $r 2>&1 | 
            tee $tmpdir/$i.dirlist.log ; 
    done < $tmpdir/$i.dirlist &
done

编辑:由于我上面的方法不能说服你,让我们尝试一些完全不同的方法。首先,创建一个您想要运行的所有进程的列表并将它们存储在一个数组中:

processes=()                      # create an empty bash array
for i in $(sed 1 $rsyncs); do
  while read r; do 
                                  # add the full rsync command line to the array
    processes+=("rsync $rsyncopts backup@$host:$remotepath/$ri $r 2>&1 | tee $tmpdir/$i.dirlist.log");
  done < $tmpdir/$i.dirlist 
done

一旦你有了那个数组,启动 200 个进程,然后进入一个循环等待一个进程完成并启动下一个:

for ((j=0;j<200;j++)); do
  $processes[$j]&                 # launch processes in background
done

while [ ! -z "$processes[$j]" ] ; do
  wait                            # wait one process finishes
  $processes[((j++))]&            # launch one more process
done

请试试这个并告诉我们。

【讨论】:

  • 好的,但变化不大。从每个文件 $tmpdir/$i.dirlist 中一个一个地运行每个命令不是问题。问题是当每个文件中有例如 100 个命令时 - 还有 100 个文件,所以简单的数学 100*100 = 10.000 同时运行命令! :/这是我的主要问题,如何管理它以仅从每个文件运行 1 个命令(文件太多 100)现在等到所有作业完成后再继续(例如 - for loop - ps auxf |grep .... |wc -l ) 如果
  • 使用您的解决方案,它以错误结束:语法错误接近意外标记 `(' for line where is : $processes[((j++))]&
【解决方案2】:

有一个使用例子

for ARG in  $*; do
    command $ARG &
    NPROC=$(($NPROC+1))
    if [ "$NPROC" -ge 4 ]; then
        wait
        NPROC=0
    fi
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2014-10-07
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多