加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – Shell – 管道到文件中的多个命令

发布时间:2020-12-15 22:47:42 所属栏目:安全 来源:网络整理
导读:我想在管道输入上运行2个命令,并希望打印(到stdout)两者的输出. 每个命令都是grep,sed和awk的组合. 这两个命令都必须位于单个.sh文件中. 示例命令: cat mult_comm.sh sed 's/World/Boy/g'|grep Boy ; grep World# Inputcat input.logHello World# This comm
我想在管道输入上运行2个命令,并希望打印(到stdout)两者的输出.

每个命令都是grep,sed和awk的组合.

这两个命令都必须位于单个.sh文件中.

示例命令:

cat mult_comm.sh       
sed 's/World/Boy/g'|grep Boy ; grep World

# Input
cat input.log
Hello World

# This command HAS to work EXACTLY like this
cat input.log | bash mult_comm.sh

预期产出

Hello Boy
Hello World

实际输出

Hello Boy

我尝试过使用三通

cat mult_comm.sh
tee >(sed 's/World/Boy/g'|grep Boy) | grep World

但这只是给出了

Hello World

我可以根据需要修改.sh文件,但无法更改管道命令.有任何想法吗?

这类似于OS X / Linux: pipe into two processes?和Pipe output to two different commands,但我无法弄清楚如何在脚本中使用命名管道.

解决方法

当你执行

tee >(some_command)

bash创建一个子shell来运行some_command.子shell的stdin被分配给管道的读数的一半. bash在命令行中留下此管道的名称,以便tee将其输入泵入管道.子壳的stdout和stderr保持不变,因此它们仍然与tee相同.

所以,当你执行

tee >(some_command) | some_other_command

现在,bash首先创建一个运行tee的进程,并将其stdout分配给管道的写入一半,另一个进程运行some_other_command,其stdin分配给同一管道的读取一半.然后它创建另一个进程运行some_command,如上所述,将其stdin分配给另一个管道的读取一半,并保持其stdout和stderr不变.但是,stdout已经被重定向到some_other_command,这就是some_command继承的内容.

在你的实际例子中,

tee >(sed 's/World/Boy/g'|grep Boy) | grep World

我们最终得到:

-->  sed 's/World/Boy/g' -->  grep Boy --
                 /                                         
input --> tee --<                                           
                                                            
                  ----------------------------------------------> grep World

在OP中链接的一个问题中,有一个(未被接受但是正确的)答案是F. Hauri,我在这里修改过:

echo Hello World |
((tee /dev/fd/5 | grep World >/dev/fd/4) 
           5>&1 | sed 's/World/Boy/' | grep Boy) 4>&1

如上所述阅读bashisms需要一些练习.重要的是那个

( commands ) 5>&1

创建一个子shell(())并为该子shell赋予一个编号为5的fd,最初从stdout(5>& 1)复制.在子shell中,/ dev / fd / 5指的是那个fd.在子shell中,可以重定向stdout,但是在将stdout复制到fd5之后会发生这种情况.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读