如果调用而不先重定向它,是否可以foo.sh
从内部接收/重定向 stderr :?bar.sh
foo.sh | bar.sh
foo.sh
#!/bin/bash
echo "hello world" >&2
酒吧.sh
#!/bin/bash
sed -Eu 's/world/everyone/g'
user@pc$ ./foo.sh | ./bar.sh
hello world
user@pc$ ./foo.sh 2>&1 | ./bar.sh
hello everyone
bar.sh
即使用户意外地像第一个示例中那样调用它,是否可以使行为像第二个示例一样?
顺便说一句,foo.sh
可以是任何写入stderr
.我只是对如何从 接收它感兴趣bar.sh
。
答案1
由于这个想法是过滤掉 stderr 上的数据,因此有一种更好的方法可以做到这一点,而无需合并流或丢失所有 stderr:my_command 2> >(grep --invert-match secret_regex >&2)
语法解释:
2>
说“将标准错误发送到命令中的下一个单词”>(some_command)
说把它之前的东西发送到标准输入命令的。>&2
最后发送grep
输出(行不是匹配秘密)回到标准错误。
示例,显示 stdout 和 stderr 在过滤后如何完好无损:
$ (echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)
output
error
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) 2>/dev/null
output
$ ((echo output; echo error >&2; echo secret >&2) 2> >(grep --invert-match secret >&2)) >/dev/null
error
原始答案:当您调用 时./foo.sh | ./bar.sh
,标准错误foo.sh
会出现在 shell 设置的任何位置(即在两个命令运行之前)。我不认为(没有根访问权限)可以bar.sh
“劫持”标准错误所指向的位置,因为这将是一个很大的安全漏洞:恶意进程可能会劫持某些打印敏感信息的命令的输出。
答案2
bash
提供一个简写:
如果|&使用时,command 的标准错误除了其标准输出外,还通过管道连接到 command2 的标准输入;它是简写2>&1 |