bash - bash循环的多处理
问题描述
我有一个非平凡的 Bash 脚本,大致采用以下形式:
# Initialization
<generate_data> | while read line; do
# Run tests and filters on line
if [ "$tests_pass" ]; then
echo "$filtered_line"
fi
done | sort <sort_option> | <consume_data>
# Finalization
与过滤器相比,生成器消耗的处理资源最少,当然,在所有过滤数据都可用之前,排序操作无法开始。因此,过滤器,由几个循环和条件组成的级联用 Bash 原生编写,是处理瓶颈,运行此循环的单个进程会消耗整个核心。
一个有用的目标是将这个逻辑分布在几个子进程中,每个子进程都运行单独的过滤器循环,而这些子进程又会消耗来自生成器的行块,并且每个子进程都会产生连接到排序操作中的输出块。此类功能可通过 GNU Parallel 等工具获得,但使用它们需要调用外部命令才能在管道中运行。
是否有任何方便的工具或功能可以使脚本上的操作可以分布在多个进程中,而不会破坏脚本的整体结构?我不知道 Bash 内置功能,但肯定会有用。
解决方案
调用外部命令的问题是在将过滤器逻辑移动到可以独立调用的某些命令方面缺乏代码可管理性。
如果这就是不使用 GNU Parallel 的原因,那听起来你好像不知道parallel --embed
.
--embed
正是因为人们需要将 GNU Parallel 放在与其余代码相同的文件中。
[output from parallel --embed]
myfilter() {
while read line; do
# Run tests and filters on line
if [ "$tests_pass" ]; then
echo "$filtered_line"
fi
done
}
export -f myfilter
<generate_data> | parallel --pipe myfilter | sort <sort_option> | <consume_data>
即使未安装 GNU Parallel,生成的脚本也会运行。
推荐阅读
- javascript - 我想从下面的代码中获取登录 ID 和密码
- vue.js - 我想添加“checkAll/uncheckAll”事件
- java - NoiseGator(主动降噪软件)功能在我的 JAVA 应用程序中的使用
- android - 清除edittext时发生奇怪的崩溃
- django-rest-framework - 当 JWT 中的刷新令牌过期时,我们如何才能在同一个会话中存活?
- c - 在 ncat 源代码中将 STDOUT 更改为文件
- laravel - 创建 x-jet-dialog 模态和 x-jet-confirmation 模态不能一起工作
- typescript - 如何使用 CDK 在 Postgres RDS 中创建表?
- latex - 使用 tufte-latex 包时未定义的控制序列
- android - Kotlin - 内部类中不允许伴随对象