如何在从我产生的工作中获取一行标准输出时阻止 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 而不是终端运行时才有效