【问题标题】:Bash: read stdin from file and write stdout to fileBash:从文件中读取标准输入并将标准输出写入文件
【发布时间】:2023-10-22 10:15:02
【问题描述】:

我正在尝试运行一个应用程序(比如说top),以便它从标准输入文件读取并从标准输出写入另一个文件。

目前我有

mkfifo stdin.pipe
(tail -f stdin.pipe) | top

它按预期工作,因为我可以 echo 该文件和顶部将接收它。 但我无法重定向 top 的输出。 我怎样才能做到这一点?

编辑:

好的,让我们从头开始。 我正在测试这个:

cat test.sh

echo Say something
read something
echo you said $something

【问题讨论】:

  • 您确定top 是从stdin 读取的吗?我的没有。您可以使用-b(批处理)选项重定向来自top 的输出:top -n 1 -b > gash
  • @cdarke 对不起,你是对的。我正在用另一个应用程序进行测试。顶部的工作方式不同。有没有办法可以将标准输入和标准输出映射到文件并使用它们来控制 cli 应用程序?

标签: linux bash


【解决方案1】:

有没有办法可以将标准输入和标准输出映射到文件并使用它们来控制 cli 应用程序?

听起来您正在寻找 coprocesses,在 4.0 中添加到 Bash。

coproc cat                    # Start cat in background
echo Hello >&${COPROC[1]}     # Say "Hello" to cat
read LINE <&${COPROC[0]}      # Read response
echo $LINE                    # cat replied "Hello"!

在 4.0 之前,您必须使用两个命名管道来实现这一点。

【讨论】:

  • 有趣的补充!
【解决方案2】:

让我们忘记top,这似乎是一个红鲱鱼。

要将标准输入或标准输出映射到文件,您可以使用重定向:

some_program < input_file          # Redirects stdin

another_program > output_file      # Redirects stdout

甚至:

yet_another  < input_file > output_file

【讨论】:

  • 这是异步还是同步?我刚刚用 2 行 bash 对其进行了测试,它会说“嗨”,等待输入,然后说“再见”。将某些内容重定向到 input_file 后(也就是应用程序完成运行时),我能够在 output_file 中看到输出
  • 如果您在程序之间进行通信,则使用匿名管道,这将比使用临时文件更有效。取决于你在这种情况下同步/异步的意思,但所有的 shell IO 都是缓冲的。每次重定向后都会刷新缓冲区并关闭文件,但如果程序正在读取而正在写入(写入文件,而不是管道),您可能会遇到问题。
  • 问题是我正在尝试从 PHP 控制 CLI 应用程序,所以我无法将句柄保存到管道,这就是为什么我需要能够读取/写入文件的原因.如何强制刷新输出而不是缓冲?
  • 使用命名管道而不是文件,您可以像文件一样重定向到命名管道(嗯,实际上,它是一个文件)。您还可以从 PHP 中读取命名管道,就像它是一个文本文件一样。
  • 您确定这将适用于我在问题中发布的示例脚本吗? (编辑部分)。我刚刚创建了 mkfifo inout 并运行了我的脚本。我希望在cat out 之后得到Say something,但我什么也没得到。