Shell-Script

在 bash 腳本中一次啟動 100 個程序

  • August 27, 2022

在 bash 腳本中,我有一個這樣的程序

for i in {1..1000}
do
  foo i
done

我用參數呼叫函式foo1000 次的地方i

如果我想讓它在多程序中執行,但不是一次全部執行,我該怎麼辦?

所以如果我有

for i in {1..1000}
do
  foo i &
done

它會一次啟動所有 1000 個程序,這不是我想要的。

有沒有辦法確保始終有 100 個程序在執行?如果某些過程完成,則開始一些新的過程,直到完成所有 1000 次迭代。或者,我可以等到所有 100 個完成後再執行另外 100 個。

zsh而不是bash

autoload -Uz zargs
zargs -P100 -I{} -- {1..1000} -- foo {}

但是如果你有 GNU xargs,你也可以這樣做(在zsh,ksh93bash):

xargs -I{} -P100 -a <(echo {1..1000}) foo {}

foo不過必須是一個獨立的命令。它不適用於 shell 函式或內置函式。

如果您可以作為組執行,請嵌套一個循環:

#! /bin/bash

date '+%T.%N'
for j in {1..3}; do
   for k in {1..3}; do
       (( ++i ))
       ( sleep 2.0 && printf 'Foo %d\n' $i ) &
   done
   wait
   date '+%T.%N'
   printf 'Batch %d ends\n' $j 
done
date '+%T.%N'

結果,顯示時間重疊:

$ ./aBatch
19:55:17.078476713
Foo 1
Foo 2
Foo 3
19:55:19.094302514
Batch 1 ends
Foo 4
Foo 6
Foo 5
19:55:21.114530543
Batch 2 ends
Foo 7
Foo 9
Foo 8
19:55:23.132184671
Batch 3 ends
19:55:23.135792952
$ 

這在 GNU 並行中是一樣的。這樣做的好處是,如果執行執行不同的時間,parallel將啟動進一步的程序,而無需等待批處理中的其他程序。

#! /bin/bash
#.. The script ./aFoo

   sleep 2 && printf 'Foo %d\n' $1

命令:

$ date '+%T.%N'; parallel -j 3 ./aFoo -- {1..9}; date '+%T.%N'
20:11:44.446042653
Foo 3
Foo 1
Foo 2
Foo 4
Foo 5
Foo 6
Foo 7
Foo 8
Foo 9
20:11:50.503324162
$ 

引用自:https://unix.stackexchange.com/questions/715015