Bash:遍历文件并读取子字符串作为参数,执行多个实例

Bash: Loop through file and read substring as argument, execute multiple instances

现在怎么样

我目前在 windows 下有一个脚本 运行ning,它经常从服务器列表中调用递归文件树。

我使用 AutoIt(作业管理器)脚本执行 30 个 lftp 并行实例(仍然 windows),这样做:

lftp -e "find .; exit" <serveraddr>

用作作业管理器输入的文件是纯文本文件,每一行的格式如下:

<serveraddr>|...

其中“...”是不重要的数据。我需要 运行 多个 lftp 实例以实现最佳性能,因为单实例性能取决于服务器的响应时间。

每个 lftp.exe 实例将其输出通过管道传输到名为

的文件
<serveraddr>.txt

需要怎样

现在我需要将这一切移植到 linux(Ubuntu,安装了 lftp)专用服务器。根据我以前非常(!)有限的 linux 经验,我想这会很简单。

我需要写什么,用什么写?例如,我是否还需要工作人员脚本,或者这可以在一个脚本中完成吗?我如何从文件中读取(我想这将是简单的部分),以及如何保持最大值。 30 个实例的数量 运行ning(甚至可能超时,因为极度无响应的服务器会阻塞队列)?

谢谢!

并行处理

我会使用 GNU/parallel。它不是默认分发的,但可以从默认包存储库为大多数 Linux 分发安装。它是这样工作的:

parallel echo ::: arg1 arg2

将并行执行 echo arg1echo arg2

所以最简单的方法是创建一个脚本,在 bash/perl/python 中同步您的服务器 - 无论您喜欢什么 - 然后像这样执行它:

parallel ./script ::: server1 server2

脚本可能如下所示:

#!/bin/sh
#[=11=] holds program name,  holds first argument.
# will get passed from GNU/parallel. we save it to a variable.
server=""
lftp -e "find .; exit" "$server" >"$server-files.txt"

lftp 似乎也适用于 Linux,因此您无需更改 FTP 客户端。

最大 运行。一次 30 个实例,像这样传递 -j30parallel -j30 echo ::: 1 2 3

正在读取文件列表

现在如何将包含 <server>|... 个条目的规范文件转换为 GNU/parallel 个参数?简单 - 首先,过滤文件以仅包含主机名:

sed 's/|.*$//' server-list.txt

sed 用于使用正则表达式等替换内容。这将去除第一个 | 到行尾 ($) 之后的所有内容 (.*)。 (虽然 | 通常表示正则表达式中的替代运算符,但在 sed 中,它需要转义才能像那样工作,否则它只表示普通的 |。)

现在您有了服务器列表。如何将它们传递给您的脚本?用xargsxargs 会将每一行都当作可执行文件的附加参数。例如

echo -e "1\n2"|xargs echo fixed_argument

将运行

echo fixed_argument 1 2

所以在你的情况下你应该这样做

sed 's/|.*$//' server-list.txt | xargs parallel -j30 ./script :::

注意事项

确保不要在每个并行任务中将结果保存到同一个文件,否则文件会损坏 - coreutils 很简单并且不会实现任何锁定机制,除非您自己实现它们。这就是为什么我将输出重定向到 $server-files.txt 而不是 files.txt.