I'm wondering why the following prints the first command last?
file=$(printf .tar.gz & printf test)
echo $file
It outputs test.tar.gz
but I'd expect .tar.gztest
.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityI'm wondering why the following prints the first command last?
file=$(printf .tar.gz & printf test)
echo $file
It outputs test.tar.gz
but I'd expect .tar.gztest
.
The order of asynchronous commands is not guaranteed and shall depend on the shell and operating system scheduler.
A simple test (run with zsh
on Mac OSX El Capital):
for shell in bash ksh zsh mksh yash dash; do
printf '[%s]\n' "$shell"
"$shell" -c 'file=$(printf .tar.gz & printf test); echo "$file"'
done
[bash]
test.tar.gz
[ksh]
test.tar.gz
[zsh]
.tar.gztest
[mksh]
.tar.gztest
[yash]
test.tar.gz
[dash]
test.tar.gz
On my Ubuntu 14.04 VM, all of those shells produce test.tar.gz
.
This is because &
sends the first command to background, and after finishing printf test
the background command from the subshell shows the info before the subshell exits. producing a test.tar.gz
in debug mode you can see the order of the commands as
++ printf test
++ printf .tar.gz
+ file=test.tar.gz
+ echo test.tar.gz
Hope is a bit clearer now,