如何在从我产生的工作中获取一行标准输出时阻止 bash

Posted

技术标签:

【中文标题】如何在从我产生的工作中获取一行标准输出时阻止 bash【英文标题】:how can I make bash block on getting a line of stdout from a job that I have spawned 【发布时间】:2018-02-07 23:41:14 【问题描述】:

我需要在 shell 脚本中启动一个进程。 (这是一个特殊的日志记录进程。)它需要在大部分 shell 脚本中存活,而其他一些进程会运行,最后我们将杀死它。

我遇到的一个问题是我需要启动这个进程,并等待它“预热”,然后再继续启动更多进程。

我知道我可以使用read 等待来自管道的一行输入,并且我知道我可以使用& 生成一个子进程。但是当我将它们一起使用时,它并没有像我预期的那样工作。


作为模型:

当我运行这个(顺序)时:

(sleep 1 && echo "foo") > read

我的整个 shell 阻塞了 1 秒钟,foo 的回声被读取消耗,正如我所料。

我想做一些非常相似的事情,除了我并行运行"foo" 作业:

(sleep 1 && echo "foo" &) > read

但是当我运行它时,我的 shell 根本不会阻塞,它会立即返回——我不知道为什么读取不等待在管道上打印一行?

是否有一些简单的方法可以将“生成作业”(&) 与捕获标准输出管道在原始外壳中结合起来?


一个非常接近我实际需要的例子是,我需要以某种方式重新表述,

(sleep 1 && echo "foo" && sleep 20 &) > read; echo "bar"

我需要它在一秒钟后打印"bar",而不是立即打印,或者在 21 秒后打印。

【问题讨论】:

检查this是否对你有用。 我认为它可能很有用,谢谢!我的意思是,在他的示例中,读者正在阻塞尚未写入的管道......我没有意识到命名管道具有不同的语义(这是发生了什么?)我的示例中没有实际的管道或其他东西?我想知道,这种效果需要命名管道吗?我希望我对 shell 有更多了解 @LuisMuñoz 你的链接完全解决了我的问题,谢谢!会接受作为答案 很高兴听到。发布他回答自己,因为我没有写任何代码:)。如果您仍想表示感谢,请单击第一条评论左侧的向上箭头(此评论添加了一些有用的内容...)。 some-command > read 是重定向语法,它将创建一个名为 read 的文件。 【参考方案1】:

这是一个使用命名管道的示例,与我最终使用的非常接近。感谢 Luis 建议命名管道的 cmets。

#!/bin/sh

# Set up temporary fifo
FIFO=/tmp/test_fifo
rm -f "$FIFO"
mkfifo "$FIFO"

# Spawn a second job that writes to FIFO after some time
sleep 1 && echo "foo" && sleep 20 >$FIFO &

# Block the main job on getting a line from the FIFO
read line <$FIFO

# So that we can see when the main job exits
echo $line

还要感谢评论者 Emily E.,我发布的行为不端的示例确实是写入名为 read 的文件,而不是使用 shell 内置命令 read

【讨论】:

以上是关于如何在从我产生的工作中获取一行标准输出时阻止 bash的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 Jupyter Notebook 中的 stderr 输出?

如何阻止另一个域访问并从我的网站获取结果?

从子进程读取的实时标准输出仅在从 PyCharm 而不是终端运行时才有效

如何将在从控制台获取的 URL 中找到的特定字符串替换为在 Ruby 文本文件中写入的每一行中找到的文件内容?

阻止写入标准输出

如何从我的 jquery 函数中获取表行中选定选项的值