我正在寻找一种 bash 单行代码,它可以将 stdin 复制到 stdout 而无需交错。到目前为止,我找到的唯一解决方案是使用 tee
,但这确实会产生交错输出。这是什么意思:
如果例如f
读取的文件
a
b
我要执行
cat f | HERE_BE_COMMAND
获得
a
b
a
b
如果我使用 tee -
作为命令,输出通常类似于
a
a
b
b
对于干净的解决方案有什么建议吗?
澄清
cat f
命令只是输入来源的一个示例。实际上,它是一个只能(应该)执行一次的命令。我还想避免使用临时文件,因为处理的数据有点敏感,并且当执行的命令被中断时,临时文件总是容易出错。此外,我对涉及额外脚本(如上所述,它应该是一个 one-liner)或需要在实际复制命令之前执行的准备命令的解决方案不感兴趣。
最佳答案
解决方案一:
<command_which_produces_output> | { a="$(</dev/stdin)"; echo "$a"; echo "$a"; }
通过这种方式,您将标准输入中的内容保存在 a
中(请选择一个更好的名字),然后 echo
'ing 两次。
公告$(</dev/stdin)
是一种类似但更有效的方法来做 $(cat /dev/stdin)
.
方案二:
使用 tee
通过以下方式:
<command_which_produces_output> | tee >(echo "$(</dev/stdin)")
在这里,您首先写入标准输出(这就是 tee
所做的),然后写入由 process substitution 创建的 FIFO 文件。 :
>(echo "$(</dev/stdin)")
例如,查看它在我的系统中创建的文件:
$ echo >(echo "$(</dev/stdin)")
/dev/fd/63
现在,echo "$(</dev/stdin)"
部分只是我发现在打印之前首先读取整个文件的方式。它echo
这是从进程替换的标准输入中读取的内容,但是一旦读取了所有输入(不像 cat
那样逐行打印)。
关于bash - 将标准输入复制到标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33233811/