Korn 中的排队命令 shell

Queuing commands in Korn shell

我正在使用 AIX Korn shell 执行 Perl 脚本,该脚本接受从 1 到 50 的数字参数并在后台同时运行它们。有没有办法像 5 这样限制后台进程?如果一个完成,执行下一个。我当前的代码只是在后台执行所有这些代码。

i=1; while [[ $i -le 50 ]]; do perl some_script.pl $i &; ((i+=1)); done;

比如2完成了,就执行下一个6,以此类推

KSH 有多种版本。原始的 Korn Shell、ksh88 是 IBM AIX 自版本 4 (/usr/bin/ksh) 以来的默认值 shell。但他们也支持 Enhanced Korn Shell、ksh93 (/usr/bin/ksh93),后者具有更多的附加功能。在这种情况下,正是那些花里胡哨的东西让生活变得轻松:

KSH93: 在 KSH93 中,你有一个 shell 变量 JOBMAX 为你做的:

JOBMAX: This variable defines the maximum number of running background jobs that can run at a time. When this limit is reached, the shell will wait for a job to complete before starting a new job.

JOBMAX=5
i=1; while [[ $i -le 50 ]]; do perl some_script.pl $i &; ((i+=1)); done;

顺便说一句。您可能有兴趣改用 for 循环。

JOBMAX=5
for i in $(seq 1 50); do perl some_script.pl "$i" &; done

KSH: 如果您不能使用 KSH93 并且必须坚持使用 POSIX 2 兼容的 KSH,您可以考虑使用 xarg,但前提是它允许 --max-procs 标志。

seq 1 50 | xargs -I{} --max-procs=5 perl some_script.pl {}

可悲的是,AIX does not support the --max-procs flag

所以,你必须自己构建一些东西:

procmax=5
for i in $(seq 1 50); do
   perl some_script.pl "$i" &;
   (( i%procmax == 0 )) && wait
done

不幸的是,这并不是真正的并行版本,因为它会等到前 5 个进程完成后再开始下一批 5 个进程。

所以,你可以看看 jobs 并用它做点什么:

procmax=5
checkinterval=1
for i in $(seq 1 50); do
  perl some_script.pl "$i" &;
  while [[ $(jobs -l | wc -l) -ge "$procmax" ]]; do
    sleep "$checkinterval";
  done
done

由于sleep,这仍然不是完全平行的,但它必须这样做。