【问题标题】:Process a line in bash as is appears按原样处理 bash 中的一行
【发布时间】:2013-06-25 10:27:46
【问题描述】:

假设我有 2 个 bash 命令:

$ A
apple
pear
lemon

A 写得非常快,但在“lemon”成功终止后等待 1 分钟。

我希望将每一行作为 B 的输入单独并立即处理。 但是我不想等待 A 终止,而是为每个快速出现的行调用一个新的 B。然后 B 会在 A 的输出中添加一些东西让我们说:

$ A <for every line appearing> B
1 apple
1 pear
1 banana

如何用 bash 做到这一点?

更新

这里是原始命令:

$sudo alive6 -l eth1 -W 0.2 | sed -e 's/Alive: \(.*\) \[ICMP echo-reply\]/\1%eth0/' -e'/Scanned.*/d' -e'//d'

立即响应,而

$sudo alive6 -l eth1 -W 0.2 | sed -e 's/Alive: \(.*\) \[ICMP echo-reply\]/\1%eth0/' -e'/Scanned.*/d' -e'//d' | while read l; do echo $l; done

似乎在等待alive6完成

【问题讨论】:

  • 这是一个有用的记录,我将它添加到我的收藏夹中。顺便说一句,我猜你没有办法修改A的行为?

标签: performance bash shell unix pipe


【解决方案1】:
A | while read -r l; do B &; done

B 在后台运行以解决以下要求:将作为 B 的输入单独处理的行 立即

【讨论】:

  • 如果B 读取标准输入,您需要use a different file descriptor
  • 你为什么要后台B
  • @l0b0 后台处理是我如何解决“作为 B 的输入单独和立即处理的行”要求。
  • “即时”与“异步”不同。这个解决方案最终会用B 的执行时间改组行。
  • 有趣的是,这并没有让它更快。我实际上已将 sed 作为 B 命令。一个简单的例子,比如 ls -l && sleep 3 | sed 's/.*/&/' |读 l;回声 $l; done 确实有效。
【解决方案2】:

使用unbuffer 禁用A 的行缓冲。

$ unbuffer A <for every line appearing> B

【讨论】:

  • @icedwater:而且 bash 脚本只有在安装了 bash 后才能工作。
  • 是的,但您在系统上找到bash 的可能性比在unbuffer 上找到的可能性更大。
【解决方案3】:

在 Bash 中:

while read -r -u 9 line || [ -n "$line" ]
do
    B "$line"
done 9< <(A)
  • 即使A 打印反斜杠也有效。
  • 即使A 的输出以换行符结尾也能正常工作。
  • 即使B 读取标准输入也可以工作,但如果它出于某种原因读取文件描述符 9,则不能。在这种情况下,您必须使用mkfifo 创建一个管道。
  • 同步运行B,异步处理A的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多