基本上,我试图理解这些命令之间的区别:
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 _ tee f.txt 尤洛 user@localhost ~$ echo yolo _ tee t.txt 尤洛
但是在进程替换中,echo会发生一些奇怪的事情。
user@localhost ~$ cat <<< yolo > >(tee f.txt) 尤洛 user@localhost ~$ echo yolo > >(tee t.txt) user@localhost ~$ yolo
终端在打印文本之前返回控件。,为什么在这种情况下我更早得到控制?
这肯定与进程如何打开以及文件描述符如何在进程之间传递有关,但我已经达到了知识的极限。
如果我把它输到其他地方,一切都会恢复正常,例如echo yolo > >(tee t.txt) | cat。
更奇怪的是,xargs在echo中工作得很好:
user@localhost ~$ xargs echo <<< yolo > >(tee t.txt) 尤洛
但是你可以说xargs是这里的主要程序,而不是echo。
如果我使用cat来替换输入进程,则结果是混合的:
cat < <(echo yolo) > >(tee t.txt)
有时它会给我这样的感觉:
user@localhost ~$ cat < <(echo yolo) > >(tee t.txt) user@localhost ~$ yolo
有时这是:
user@localhost ~$ cat < <(echo yolo) > >(tee t.txt) 尤洛
因此,我想这可能与系统执行命令的速度有关,这使它变得不可预测。
这是否意味着输出进程替换(例如,本例中的tee )在后台运行?
发布于 2020-02-25 13:23:39
我想我找到它了..。
过程替代..。进程asynchronously,运行
list,其输入或输出显示为文件名。
一旦命令(或分叉进程完成),控制返回到终端并显示下一个提示符。我最初怀疑echo的内置可能起到了作用,但它实际上只是扭曲了时间。也就是说,一旦使用> >(tee t.txt),tee何时才能打印到控制台并不完全是确定性的。
在这个问题上,尝试如下(对于您的第三个示例):
$ cat <<< yolo > >(sleep 1; tee f.txt)
$ yolo相对于:
$ { echo yolo; sleep 1 ;} > >(tee t.txt)
yolo
$不同的是,正如前面提到的,>(list)进程替换是异步执行的。尝试这两个示例中的前一个示例,即使对于sleep来说模拟一个长时间运行的过程具有更大的价值。当您继续使用shell时,它会一直存在(实际上,即使您终止了它,在这种情况下,它也会被复制,但您仍然可以在进程列表中看到;附带注意:“由于命令替换而运行的命令忽略了键盘生成的作业控制信号SIGTTIN__、SIGTTOU__和SIGTSTP__。”与下面的异步(&)执行示例不同,即使是松散终端也不会杀死它们。)
另一方面,管道:
如果管道不是异步执行的(请参阅列表),shell将等待管道中的所有命令完成。
在管道执行完所有命令之前,Shell不会恢复控制(下一个命令不会执行)。
尝试:
$ echo yolo | (sleep 1; tee f.txt)
yolo
$与(类似于使用>(list))相反:
echo yolo | ((sleep 1; tee f.txt) &)
$ yolo(实际上并不需要双子shell,我只是使用它来抑制正在运行的shell中的作业控制消息)。
https://stackoverflow.com/questions/60394727
复制相似问题