【发布时间】:2020-06-09 04:38:36
【问题描述】:
基本上我想了解这些命令之间的区别:
cat <<< yolo | tee f.txt
echo yolo | tee t.txt
还有那些命令:
cat <<< yolo > >(tee f.txt)
echo yolo > >(tee t.txt)
前两个命令的结果完全相同:打印“yolo”,然后终端返回控制权,这正是我所期望的。
[user@localhost ~]$ cat
yolo
[user@localhost ~]$ echo yolo | tee t.txt
yolo
但是使用进程替换,echo 会发生一些奇怪的事情。
[user@localhost ~]$ cat >(tee f.txt)
yolo
[user@localhost ~]$ echo yolo > >(tee t.txt)
[user@localhost ~]$ yolo
终端返回控件在文本被打印出来之前。 在这种情况下,为什么我会更早获得控制权?
这一定与进程的打开方式以及文件描述符如何在进程之间传递有关,但我有点达到了我的知识极限。
如果我通过管道将它连接到其他任何东西,一切都会恢复正常,例如echo yolo > >(tee t.txt) | cat.
更奇怪的是,xargs'ing into echo 效果很好:
[user@localhost ~]$ xargs echo >(tee t.txt)
yolo
但是你可以说xargs是这里的主程序,而不是echo。
如果我使用 cat 的输入进程替换,我会得到不同的结果:
cat < <(echo yolo) > >(tee t.txt)
有时它会给我这个:
[user@localhost ~]$ cat >(tee t.txt)
[user@localhost ~]$ yolo
有时是这样的:
[user@localhost ~]$ cat >(tee t.txt)
yolo
所以我猜这可能与系统执行命令的速度有关,这使得它无法预测。
这是否意味着输出进程替换(例如本例中的tee)在后台运行?
【问题讨论】:
-
这似乎与以下事实有关您应该再次获得与前三个相同的行为。至少这是我观察到的。
-
无论我打电话给
/usr/bin/echo yolo > >(tee t.txt)还是'echo' yolo > >(tee t.txt)(带引号)我都得到与echo yolo > >(tee t.txt)相同的结果。但是如果这是与性能相关的,那么调用 /usr/bin/echo 可能会稍微慢一些/更快,具体取决于系统,导致问题在不同的计算机上出现/消失。 -
专业提示:您可以通过管道将进程替换的输出同步到另一个进程,这样另一个进程在输入流打开之前不会退出并且 bash 会等待它,所以它会有效地等待进程替换。所以
echo yolo >(tee t.txt) | cat会同步输出。 -
@KamilCuk 是的,这实际上是我的建议之一;)但这并不是一个真正的选择,因为在我的情况下,我对
echo的退出代码感兴趣,我想避免使用 PIPESTATUS(是的,我知道echo总是返回 0,但您可能已经猜到我最终会使用另一个程序)。 -
为什么要避免使用 PIPESTATUS?这会起作用:
{ echo yolo; echo $? > "temporary_tile"; } | tee t.txt;
标签: bash echo cat process-substitution