同时在文件夹中同时运行Bash脚本


10

假设我.sh在一个文件夹(my_folder)中有五个Bash()脚本,它们的名称如下:

script_1.sh
script_2.sh
script_3.sh
script_4.sh
script_5.sh

我该如何编写第六个Bash脚本或仅编写一个可以一起运行所有这些脚本的划线器?

我需要五个脚本同时开始一起运行,而不是一个接一个地运行。


Answers:


12

GNU parallel非常适合这种事情。使用安装,sudo apt install parallel然后:

parallel -j0 ::: my_folder/*sh

-j吨并行多少进程运行控制,并-j0表示“所有的人”。将其设置为另一个值(例如-j20),以分批运行脚本。


1
注意:软件包中还有parallel命令moreutils。示例用法:(parallel -j 20 -- my_folder/*.sh与GNU不同parallel-j0它将一次运行一个脚本)。
jfs

1
@jfs好点。但是请注意,sudo apt install parallel它将用/usr/bin/parallelGNU parallel中的一个替换该文件。因此,只要您安装了它(如我的回答所示),它就应该可以正常工作。

是的,parallel在编写建议GNU并行的答案时,尝试使用手册中的命令失败时,我发现了这很困难。
jfs

9

要同时(并行)运行所有脚本,请使用:

script_1.sh &
script_2.sh &
script_3.sh &
script_4.sh &
script_5.sh &

要一个接一个地运行(依次),请使用:

script_1.sh &&
script_2.sh &&
script_3.sh &&
script_4.sh &&
script_5.sh

增强评论功能

如果您有200个脚本要同时运行(这可能会使计算机顺便说一句),请使用以下脚本:

#!/bin/bash
for Script in my_folder/*.sh ; do
    echo bash "$Script" &
done

使用以下命令将脚本属性设置为可执行文件:

chmod a+x /path/to/script.sh

第一次运行脚本时,它将仅回显将要执行的200个脚本的名称。当您满意时,可以选择正确的名称来编辑脚本并更改此行:

    echo bash "$Script" &

至:

    bash "$Script" &

您可以通过以下三种方法从另一个调用bash脚本:

  1. 使其他脚本可执行,#!/bin/bash在顶部添加行,并将文件添加到$PATH环境变量的路径。然后,您可以将其作为普通命令来调用;

  2. 或与源命令调用它(别名)是这样的:source /path/to/script;

  3. 或者使用bash命令来执行它:/bin/bash /path/to/script;

在OP的情况下,200个脚本中的一个或多个不包含#!/bin/bash文件中的shebang 第一行。因此,必须使用选项3.。


同时运行200个脚本

对于它们是否“同时运行”提出了评论。在典型的8 CPU系统上,25个脚本将同时共享一个CPU,但是一次只能执行一个脚本,直到时间片(以毫秒为单位)用完为止。然后,下一个作业将获得其应有的毫秒份额,然后是下一个作业,依此类推,等等。

粗略地说,我们可以说200个作业在8个CPU上“同时”运行,而不是“同时”运行,相当于每个CPU 25个作业:

线程状态

上图和下面来自Linux内核调度程序的注释

时间slice.png


谢谢..事实上,在我的实际情况下,我有200多个脚本要运行。因此,有什么方法可以用一个命令来运行所有这些文件(即不写文件名)?
aaaaa

@aaaaa我已经更改了200个脚本的答案。
WinEunuuchs2Unix

谢谢。它有效..我唯一要添加到您的最后一行的内容是“ bash”。否则我会被“拒绝权限”。
aaaaa

1
@aaaaa您实际上是希望同时运行所有200多个脚本,还是希望一次运行较少的脚本(例如10个),而其他脚本则在其中一个或多个完成时排队运行?当前正在运行的脚本数量下降到该数量以下?(如果您对这样的解决方案感兴趣,我建议用关于您拥有多少个脚本,它们倾向于运行多长时间,它们从事何种工作等信息来编辑您的问题。)
Eliah Kagan

@aaaaa感谢您的反馈。我已经更新了答案,以包括bash调用脚本的前缀。
WinEunuuchs2Unix

3

有一个工具可以阅读man run-parts

例如,我这样做:

 run-parts ${visorhome}/pbackup.d/

在我的Palm Pilot备份脚本中。 ${visorhome}/pbackup.d/

01PopulateJpilot  02Extract_Pedometer  03URLs  04google  05Books  06Weight  07Sec  08Bkgm 50hardlinks

1
@ eliah-kagan运行“ 200多个脚本”“同时”似乎是不明智的。这可能是对系统进行压力测试的好方法
waltinator

好点子。我确实认为您可能仍要提及run-parts按顺序执行脚本,而不是按OP要求一次执行所有脚本。您说对了,但是一次运行200个脚本不太可能会与运行5个脚本表现相同,即使一次运行所有脚本都不会引起任何问题,可能仍然没有必要。我评论建议的OP澄清这方面的喜好。
伊利亚·卡根

run-parts将不会运行脚本(它们的名称中带有点号:my_folder/*.sh
jfs

1
run-parts由于某些奇怪的原因,具有 非常特定的文件名要求。它不会启动带有扩展名的文件名,所以我担心这在这里不起作用。
terdon

1

使用以下命令同时运行目录中的所有*.sh脚本my_folderxargs

$ ls my_folder/*.sh | xargs -P0 -n1 bash

将并发执行的脚本数限制为10

$ ls my_folder/*.sh | xargs -P10 -n1 bash

ls在脚本中使用输出是一个不好的做法。使用find更加安全。这是这里的第一项:mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29

@Joe通常是这样。在这种情况下,我看不到任何问题。
jfs

那是因为您已经知道了。后来来这里的人可能不会。

@Joe不要盲目遵循教条。自己想一想,哪种选择比另一种选择更好。
jfs

这不是教条。我对那些很宽容。但是我已经看到ls可以发出的东西。解析人类可读的输出是不可靠的。开发人员没有保留的动力
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.