简体   繁体   English

命令替换 - Bash 中的评估顺序

[英]Command Substitution - order of evaluation in Bash

I was trying to run this seemingly simple script which should display the functionality of the -a flag of touch: diff <(stat file.o) <(touch -a file.o; stat file.o) .我试图运行这个看似简单的脚本,它应该显示 -a 标志的功能: diff <(stat file.o) <(touch -a file.o; stat file.o) The output of this command is sporadic - obviously sometimes touch gets executed after everything else has been evaluated - but in an example as: diff <(echo first) <(echo second; echo third) - the order is kept.该命令的输出是零星的 - 显然有时 touch 会在其他所有内容都被评估后执行 - 但在示例中为: diff <(echo first) <(echo second; echo third) - 顺序保持不变。 So why doesnt the first command work aswell?那么为什么第一个命令也不起作用呢?

Both commands happen at the same time.两个命令同时发生。

That is to say, touch -a file.o; stat file.o也就是touch -a file.o; stat file.o touch -a file.o; stat file.o from one process substitution and stat file.o from the other are happening concurrently.来自一个进程替换的stat file.o touch -a file.o; stat file.o来自另一个进程的 stat file.o 同时发生。

So sometimes the touch happens before the process substitution that only has a stat ;所以有时touch发生在只有一个stat的进程替换之前; that means that both the stat commands see the effect of the touch , because (in that instance) the touch happened first.这意味着两个stat命令都可以看到touch的效果,因为(在那种情况下) touch首先发生。

As an (ugly, bad-practice) example, you can observe that it no longer happens when you add a delay:作为一个(丑陋的,糟糕的做法)示例,您可以观察到添加延迟时它不再发生:

diff <(stat file.o) <(sleep 1; touch -a file.o; stat file.o)

The <( command-list ) syntax does the following: <( command-list ) 语法执行以下操作:

  1. Run command-list asynchronously异步运行命令列表
  2. Store output of command-list in a temporary file将命令列表的输出存储在临时文件中
  3. Replace itself on the command line with the path to that temporary file在命令行中将自身替换为该临时文件的路径

See Process Substitution .请参阅过程替换

The first point is likely what is tripping you up.第一点很可能是什么让你绊倒。 There is no guarantee that your first process substitution will run before your second process substitution, therefore touch -a might be executed before either call to stat .无法保证您的第一个进程替换将在您的第二个进程替换之前运行,因此touch -a可能在调用stat之前执行。

Your second example will always work as expected, because the output of each individual process substitution will be serialized.您的第二个示例将始终按预期工作,因为每个单独的进程替换的输出都将被序列化。 Even if echo second happens before echo first , they'll still be written to their respective temporary files and echo third will always happen after echo second so they will appear in the correct order in their file.即使echo second发生在echo first之前,它们仍将被写入各自的临时文件,并且echo third将始终在echo second之后发生,因此它们将在文件中以正确的顺序出现。 The overall order of the two process substitutions doesn't really matter.两个进程替换的整体顺序并不重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM