middle
我有一个无法修改的程序(让我们命名它)。
该程序执行以下步骤序列:
middle
发送一些文本到 stdout (echo Text1
)middle
调用 shell 脚本inner.sh
,传递一些文本字符串(4 KB 或更少)作为参数 (inner.sh "Deferred Message"
)middle
发送一些文本到 stdout (echo Text2
)
我的任务是创建两个 bash 脚本outer.sh
,并将inner.sh
延迟消息安排在进程生成的所有其他消息之后middle
。
生成的标准输出必须如下:
Text1
Text2
Deferred Message
要求:
outer.sh
应该调用middle
(middle
并将调用inner.sh
)。inner.sh
必须在某处记住它的参数(延迟消息)middle
终止后,outer.sh
必须调用延迟消息并将其打印到标准输出- 将会有很多
outer.sh
进程同时运行。延迟消息必须存储在当前outer.sh
进程实例的本地位置 - 禁止在文件系统中创建临时对象。 (是否可以将延迟消息存储在内存中的某个位置?)
内部.sh
# Where should I save message "$1"?
外层.sh
middle "$@"
# How should I recall and print the deferred message?
我应该在子进程中将延迟消息保存在哪里以及如何在父进程中读取它?
答案1
inner.sh
可能:
printf '%s\n' "$1" >&3
在 中outer.sh
,你可以这样做:
{ inner=$(middle "$@" 3>&1 >&4 4>&-); } 4>&1
printf '%s\n' "$inner"
内部文本通过管道传递(在命令替换中)并存储在 shell 变量中。假设middle
在调用之前不会关闭 fd 3 inner.sh
(但没有理由这样做)。
解释:
{ ... } 4>&1
。在该命令组中,最初,fd 1 和 4 都指向原始 stdout。 IOW,我们已经将outer.sh的stdout复制到fd 4上,以便能够在命令替换中恢复它$(...)
。在该命令替换中,stdout (fd 1) 是一个管道。这就是命令替换的要点。它想要抓取命令的输出。但在这里,我们不需要 的 stdoutmiddle
,我们想要它(或更确切地说是它的孩子inner.sh
)在 fd 3 上写入的内容,所以:middle 3>&1 >&4 4>&-
:对于middle
,我们将 fd 3 设为 cmdsubst 管道,这样inner.sh
写入的内容就会进入$inner
,然后我们middle
将 的 stdout 恢复到已保存fd 4 上的原始标准输出。在 fd 4 达到其目的后,我们将其关闭,因为middle
不需要对其执行任何操作。