Bash 复杂的流水线依赖
Bash complex pipeline dependencies
我正在尝试在单个 Bash 脚本中为构建并发管道建模。我知道我可以使用其他工具,但在这一点上我是出于理解 Bash。
并行安排作业很容易,最后等待所有作业也很容易。但是我想通过在任务 A.1 和任务 X 之后立即触发任务 A.2 来使其更快 运行 。为了让自己更难,任务 A.1 和任务 A.2 中的代码是相关的& 顺序,所以如果我也能保持代码顺序就好了。
#!/usr/bin/bash
{
echo "Task X"
} &
DEPENDENCY=$!
{
echo "Task A.1"
wait "${DEPENDENCY}"
echo "Task A.2"
} &
{
echo "Task B.1"
wait "${DEPENDENCY}"
echo "Task B.2"
} &
wait
这正是我想要的,但它不起作用,因为子进程不能互相等待——这是有道理的——但我希望我能以跨平台的方式实现它.
我确实有这个功能,但我无法保留 *.1 和 *.2 部分的代码
另外,如果这对 OSX 和 Linux 有效,那就太好了。我希望 Bash 专家可以插话并在 Bash 中展示一种简洁的表达方式。
正如对问题的评论所指出的,以下 Makefile 等同于您的 shell 脚本(但不涉及文件系统)
.PHONY: a1 a2 b1 b2 x
all: a2 b2
a1:
@echo "Task A.1"
b1:
@echo "Task B.1"
x:
@sleep 1.5; echo "Task X"
a2: a1 x
@echo "Task A.2"
b2: b1 x
@echo "Task B.2"
尝试使用 make -j5
以允许五个并行线程。它需要 GNU make,它适用于现有的每个平台,即使它可能不是默认分发的。初始 .PHONY:
目标确保所有任务都执行,即使名为 a1
、a2
、... 的文件碰巧存在。
使 OSX 和 Linux 工作的一种方法是使用命名管道向批处理作业发出信号,表明它们可以继续。不幸的是,它需要拆分 "Task *.1" & "Task *.2",但这是我目前能想到的最好的。
#!/bin/bash
function cleanup {
rm -f .task.a.1.done .task.b.1.done
}
trap cleanup EXIT
cleanup
mkfifo .task.a.1.done
mkfifo .task.b.1.done
{
echo "Task A.1"
echo -n "" > .task.a.1.done
} &
{
echo "Task B.1"
echo -n "" > .task.b.1.done
} &
{
echo "Task X"
}
{
cat < .task.a.1.done
echo "Task A.2"
} &
{
cat < .task.b.1.done
echo "Task B.2"
} &
wait
我正在尝试在单个 Bash 脚本中为构建并发管道建模。我知道我可以使用其他工具,但在这一点上我是出于理解 Bash。
并行安排作业很容易,最后等待所有作业也很容易。但是我想通过在任务 A.1 和任务 X 之后立即触发任务 A.2 来使其更快 运行 。为了让自己更难,任务 A.1 和任务 A.2 中的代码是相关的& 顺序,所以如果我也能保持代码顺序就好了。
#!/usr/bin/bash
{
echo "Task X"
} &
DEPENDENCY=$!
{
echo "Task A.1"
wait "${DEPENDENCY}"
echo "Task A.2"
} &
{
echo "Task B.1"
wait "${DEPENDENCY}"
echo "Task B.2"
} &
wait
这正是我想要的,但它不起作用,因为子进程不能互相等待——这是有道理的——但我希望我能以跨平台的方式实现它.
我确实有这个功能,但我无法保留 *.1 和 *.2 部分的代码
另外,如果这对 OSX 和 Linux 有效,那就太好了。我希望 Bash 专家可以插话并在 Bash 中展示一种简洁的表达方式。
正如对问题的评论所指出的,以下 Makefile 等同于您的 shell 脚本(但不涉及文件系统)
.PHONY: a1 a2 b1 b2 x
all: a2 b2
a1:
@echo "Task A.1"
b1:
@echo "Task B.1"
x:
@sleep 1.5; echo "Task X"
a2: a1 x
@echo "Task A.2"
b2: b1 x
@echo "Task B.2"
尝试使用 make -j5
以允许五个并行线程。它需要 GNU make,它适用于现有的每个平台,即使它可能不是默认分发的。初始 .PHONY:
目标确保所有任务都执行,即使名为 a1
、a2
、... 的文件碰巧存在。
使 OSX 和 Linux 工作的一种方法是使用命名管道向批处理作业发出信号,表明它们可以继续。不幸的是,它需要拆分 "Task *.1" & "Task *.2",但这是我目前能想到的最好的。
#!/bin/bash
function cleanup {
rm -f .task.a.1.done .task.b.1.done
}
trap cleanup EXIT
cleanup
mkfifo .task.a.1.done
mkfifo .task.b.1.done
{
echo "Task A.1"
echo -n "" > .task.a.1.done
} &
{
echo "Task B.1"
echo -n "" > .task.b.1.done
} &
{
echo "Task X"
}
{
cat < .task.a.1.done
echo "Task A.2"
} &
{
cat < .task.b.1.done
echo "Task B.2"
} &
wait