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)
. 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. So why doesnt the first command work aswell?
CodePudding user response:
The <( command-list ) syntax does the following:
- Run command-list asynchronously
- Store output of command-list in a temporary file
- 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
.
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. The overall order of the two process substitutions doesn't really matter.
CodePudding user response:
Both commands happen at the same time.
That is to say, touch -a file.o; stat file.o
from one process substitution and stat file.o
from the other are happening concurrently.
So sometimes the touch
happens before the process substitution that only has a stat
; that means that both the stat
commands see the effect of the touch
, because (in that instance) the touch
happened first.
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)