在Bash中没有内置并行或者并发运行命令的方法。GNU Parallel是用于构建并行运行命令的工具。

您可以使用不同的参数运行同一命令,无论它们是文件名,用户名,主机名还是从文件读取的行。

GNU Parallel提供了对许多最常见操作包括输入行,输入行的各个部分,指定输入源的不同方式等。

Parallel可以从输入源替换命令或将命令提供给多个不同的Bash实例。

有时候你运行的命令也许不需要等待上一个命令运行完成之后再运行下一个,因此你可能会想到让这些命令并行或者并发运行,减少你的任务执行时间,或者加快项目构建速度。

安装parallel

安装GNU Parallel有两种方式,第一种时从源码构建编译并安装。这种方式适用于Linux所有的发行版。

第二种使用发行版的软件管理器进行安装,如果你使用的是基于debian发行版,比如Ubuntu,Linux mint可以运行命令sudo apt install parallel安装GNU Parallel。

如果你使用的CentOS,Fedora,Open Suse等基于Redhat的Linux发行版,则需要先启用EPEL仓库,然后运行命令sudo yum -y install Parallel安装Parallel。

教程

每次使用parallel执行命令时,你可能会注意到每次都有相同说明在顶部出现。为了有更好的可读性,我们建议你了解学术引用说明后关闭它。

如需要请先运行parallel --citation命令。然后继续键入will cite,接着enter回车。即可关闭学术引用说明。

使用parallel非常简单,只需要在parallel后面连接多个命令,并且使用空格分开,例如命令parallel -vk  ::: ls 'echo foo' pwd中将会并行执行ls,echo foo,pwd命令。

还有一种常见的用法就是在parallel后面接着需要以不同参数重复运行相同的命令。parallel echo ::: A B C命令相当于同时并行运行三次echo命令。

parallel可以从标准输入中读取命令的参数,然后传递给指定命令运行。

echo 1,2 | parallel  -d, echo {}这是一个简单的示例。在这个示例parallel通过管道从标准输入读取命令的参数,然后将参数传递给后面的echo命令。

{}大括号将会被从标准输入中的参数填充,-d选项表示使用逗号作为参数分隔符。

除了读取标准输入作为参数外。Parallel也可以并行运行文件中的命令。在文件创建一系列shell命令,每个命令都做一些独立的任务。

此时,如果你使用parallel运行它,将会更快完成你的任务。比如你有一个文件, 包含一系列shell命令。你可以使用命令parallel -j 10 < file运行它。

-j选项表示同时运行的任务数,建议使用CPU的核心数。nproc命令可以找到CPU的核心数量。

如果你文件中命令并不是每一个都是独立的任务,命令之间存在先后运行的依赖,这个时候就不适合使用Parallel运行它。

如果你还是要使用Parallel运行,可以使用Parallel的-k选项。Parallel将按顺序的运行它。

parallel xargs

parallel也可以实现类似于xargs命令的能力。例如,使用parallel替换xargs压缩当前目录及其子目录中以.html作为扩展名的文件。

如果您需要保留特殊字符,例如文件名中的换行符。请使用find的-print0选项。如你需要了解更多find命令相关的说明,请参阅我们的使用find命令搜索文件教程

find . -type f -name '*.html' -print | parallel gzip

当文件数量太大而无法通过调用一次mv命令移动或者重命名文件时,可以使用Parallel从当前目录移动文件。

find . -depth 1 \! -name '.*' -print0 | parallel -0 -X mv {} destdir

如您所见,{}被替换为从标准输入读取的每一行,destdirs是你的目标目录。

Parallel提供了一种内置的机制来删除文件名的扩展名,这使其可以进行批量处理文件的格式转换或重命名。

这将使用bzip2重新压缩当前目录中所有以.gz结尾的文件,每个CPU核心运行一个作业。parallel可以从命令行获取参数。

ls *.gz | parallel -j+0 "zcat {} | bzip2 >{.}.bz2 && rm {}"

结论

至此,你知道如何使用Parallel命令用法和安装Parallel。比如使用批量重命名文件等。如果你想学习更多Parallel命令的基础,请参考GNU Parallel文档。如你有任何疑问请随时发表评论。