本文主要是介绍03-28 周四 Linux 并行工具使用xargs和parallel,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
简介
程序猿日常工作开发中,免不了要和linux服务器打交道的,如何高效的使用shell命令来实现我们的功能呢,比如说如下的场景:
- 高效统计一个目录下每个目录的空间占用
- 高效将一个服务器上的文件拷贝到其他多个服务器上。
- 高效的启动多个服务器上的进程。
诸如此类的场景,如果手动,一个一个ssh-scp,太枯燥了。因此,我们便需要高效的并行工具,启动多进程的方式来实现我们的目标。
在Linux中,并发查询多个目录的磁盘占用可以通过多种方法实现。以下是一些可以提高效率的策略:
xargs
使用xargs
与-P
参数并行执行:
xargs
命令可以将标准输入数据转换为命令行参数,并执行指定的命令。结合-P
参数,可以指定并行进程的数量。
find /path/to/search -type d -print0 | xargs -0 -I {} -P 10 du -sh {}
在这个例子中,find
命令用于查找所有目录,-print0
和xargs -0
确保了文件名中的特殊字符(如空格)被正确处理。-P 10
指定了并行进程的数量,这里设置为10,你可以根据系统资源调整这个数值。
再提供另外两个实践
统计数据模型加载时间
ls | grep 256 | xargs -t -n 1 sh -c 'egrep "module data load time" $0 | tail -n 50'
使用5个进程统计当前目录下各个目录的空间大小
ls | grep -v \^[a-k] |xargs -I {} -P 5 sh -c "du -sh {}"
使用ls| grep -v 来过滤需要的目录,其中a-k已经统计过了。
下面是结合xargs和rsync将当前目录下的所有目录同步到远端机器上。
# 使用rsync同步imagenet目录到远端的gpfs目录下。
rsync -rvza -e "ssh -p 31022" imagenet root@10.106.11.11:/gpfs
rsync -rvza -e "ssh -p 31022" valfull root@10.106.11.11:/gpfs/imagenet
# 这个是代码目录/mnt/sf-nfs/self-define/tanke/ddl/demo_code
ls | xargs -P 3 -I {} rsync -rvza -e "ssh -p 31022" {} root@10.106.11.11:/gpfs/demo_code
ls -l1 | grep '^d' | sort -k 9 | awk -F " " '{print $9}' | xargs -I {} -P 48 sh -c "du -sh {}"
下面是一些其他的例子
xargs
是一个非常有用的命令行工具,它可以构建并执行命令行,这些命令行由标准输入或管道传递的数据生成。以下是一些 xargs
的示例命令及其解释:
-
基本使用:
echo -e "apple\nbanana\ncherry" | xargs echo "Fruit: "
这个命令会将 “apple”、“banana” 和 “cherry” 作为输入,并通过
xargs
传递给echo
命令,输出为 “Fruit: apple”、“Fruit: banana” 和 “Fruit: cherry”。 -
使用
-I
选项进行替换:echo -e "apple\nbanana\ncherry" | xargs -I % echo "Fruit: %"
-I
选项允许你指定一个替换字符串(在这里是%
),它在命令中被输入项替换。输出结果与上一个例子相同,但使用了不同的方法。 -
限制并行进程数:
find . -name "*.txt" | xargs -P 5 rm -f
-P
选项允许你指定同时运行的最大进程数。在这个例子中,find
命令查找所有.txt
文件,然后xargs
并行删除这些文件,最多同时运行 5 个rm
进程。 -
使用
-n
选项指定每次调用的参数数量:seq 10 | xargs -n 2 echo "Number: "
-n
选项指定每次调用命令时传递的参数数量。在这个例子中,seq 10
生成 10 个数字,xargs
每次传递两个数字给echo
命令,输出为 “Number: 1 2”、“Number: 3 4” 等。 -
使用
-d
选项定义输入项分隔符:echo -e "apple,banana,cherry" | xargs -d ',' echo "Fruit: "
-d
选项允许你指定输入项的分隔符。在这个例子中,分隔符是逗号,
,xargs
会为每个水果名称执行echo
命令。 -
使用
-p
选项进行交互式执行:ls | xargs -p rm -f
-p
选项会在执行每个命令之前提示用户确认。在这个例子中,ls
列出当前目录的文件,xargs
准备删除这些文件,但在删除前会询问用户。 -
结合
xargs
和awk
进行复杂操作:find . -type f -name "*.txt" | awk -F '/' '{print $NF}' | sort | uniq | xargs -I % touch %
这个命令链首先查找所有
.txt
文件,然后awk
提取文件名,sort
和uniq
去除重复项,最后xargs
为每个唯一的文件名创建一个新的空文件。 -
使用
-0
和--null
选项处理包含空格和特殊字符的文件名:find . -type f -print0 | xargs -0 rm -f
-0
选项告诉xargs
输入项是以 null 字符分隔的,这对于处理包含空格、引号或其他特殊字符的文件名非常有用。
这些例子展示了 xargs
的多种用法,包括基本的文本处理、并行执行、交互式确认以及处理特殊字符和空格。在使用 xargs
时,请确保理解每个选项的含义,以避免意外的行为。
parallel
. 使用parallel
命令:
parallel
是一个shell工具,用于在多个核心上并行执行任务。如果你的系统安装了parallel
,可以使用以下命令:
find /path/to/search -type d | parallel du -sh {}
parallel
会自动根据系统的核心数来决定并行任务的数量。你也可以使用--jobs
参数来手动指定并行任务数。
parallel
是一个非常强大的命令行工具,它允许你并行执行任务。以下是一些 parallel
的例子,展示了不同参数的用法:
-
基本使用:
parallel echo ::: a b c
这个命令会并行地输出
a
、b
和c
。默认情况下,parallel
会尝试使用所有可用的 CPU 核心。 -
指定任务数:
parallel -j 4 echo ::: a b c d e f g h
使用
-j
参数来指定同时运行的任务数。在这个例子中,parallel
会尝试同时运行 4 个任务。 -
使用百分比:
parallel -j 50% echo ::: a b c d e f g h
使用百分比来指定任务数。在这个例子中,
parallel
会使用系统可用 CPU 核心的 50% 来运行任务。 -
串行任务:
parallel -j 1 echo ::: a b c
设置
-j 1
会使得所有任务串行执行,即使有多个输入项。 -
使用不同的任务模板:
parallel 'echo {} is a fruit' ::: apple orange banana
这个命令会输出每个水果名称后面跟着 “is a fruit”。
{}
是一个占位符,代表输入项。 -
使用重定向文件作为输入:
parallel 'echo {} is a fruit' :::: fruits.txt
使用
:::
从文件fruits.txt
中读取输入项。 -
并行删除多个文件:
parallel 'rm {}' ::: /path/to/file1 /path/to/file2 /path/to/file3
使用
parallel
并行删除指定的文件。请谨慎使用,因为rm
命令会永久删除文件。 -
使用shell命令作为任务:
parallel 'bash -c "echo {}; sleep 1"' ::: a b c
执行一个复杂的shell命令,这里每个任务都会输出一个字母,然后暂停1秒。
-
限制内存使用:
parallel -j 4 --block 20% 'bash -c "echo {}; sleep 1"' ::: a b c
使用
--block
参数来限制任务的内存使用。在这个例子中,每个任务将尝试使用不超过系统可用内存的 20%。 -
使用嵌套循环:
parallel 'echo {} is {}' ::: a b c ::: 1 2 3
使用两个输入列表,
parallel
会将第一个列表中的每个元素与第二个列表中的每个元素组合,并执行命令。
这些例子展示了 parallel
的一些基本用法和参数。在实际使用中,你可能需要根据具体任务调整参数。在使用 parallel
时,请确保理解每个参数的含义,以避免意外的行为。
编写脚本或使用循环:
你可以编写一个简单的shell脚本或使用循环结构来并发执行du
命令。
#!/bin/bash
directories=(/path/to/dir1 /path/to/dir2 /path/to/dir3)
for i in "${directories[@]}"; dodu -sh "$i" &
done
wait
这个脚本会并发地对每个目录执行du -sh
命令,&
将命令放入后台执行。wait
命令用于等待所有后台任务完成。
使用subprocess
模块(Python):
如果你熟悉Python编程,可以使用subprocess
模块来并发执行多个du
命令。
import subprocessdirectories = ["/path/to/dir1", "/path/to/dir2", "/path/to/dir3"]
processes = []for directory in directories:p = subprocess.Popen(["du", "-sh", directory])processes.append(p)for proc in processes:proc.wait()
这段Python代码会创建多个进程来并发执行du
命令,并等待它们全部完成。
请注意,过多的并发可能会对系统性能产生影响,特别是在磁盘I/O密集型操作如du
命令时。确保在执行并发任务时,系统资源充足,以避免不必要的性能下降。
这篇关于03-28 周四 Linux 并行工具使用xargs和parallel的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!