我试图运行这个看似简单的脚本,它应该显示触摸-a标志的功能:diff <(stat file.o) <(touch -a file.o; stat file.o)
。这个命令的输出是零星的——很明显,有时touch会在其他所有命令都计算完之后执行——但是在示例:diff <(echo first) <(echo second; echo third)
中——顺序是保持不变的。那么为什么第一个命令不能正常工作呢?
<(command-list)语法的作用如下:
- 异步运行command-list
- 将命令列表的输出保存在临时文件
- 在命令行中将自身替换为临时文件 的路径
参见进程替换。
第一点很可能是让你犯错的原因。不能保证第一个进程替换将在第二个进程替换之前运行,因此touch -a
可能在调用stat
之前执行。
您的第二个示例将始终按预期工作,因为每个单独的流程替换的输出将被序列化。即使echo second
发生在echo first
之前,它们仍然会被写入各自的临时文件,echo third
总是发生在echo second
之后,所以它们会以正确的顺序出现在它们的文件中。两个过程替换的总体顺序并不重要。
两个命令同时发生
也就是说,来自一个进程的touch -a file.o; stat file.o
和来自另一个进程的stat file.o
是并发发生的。
所以有时touch
发生在只有stat
的过程替换之前;这意味着两个stat
命令都看到了touch
的效果,因为(在那个实例中)touch
先发生了。
作为一个(丑陋的,坏实践)示例,您可以观察到,当您添加延迟时,它不再发生:
diff <(stat file.o) <(sleep 1; touch -a file.o; stat file.o)