I'm confused with the command substitution. I think command substitution as like a programming language macro. The sub shell is executed first and the $(...)
is substituted with it's standard output, before the parent command is evaluated. But is this all the truth?
When I try to execute the following command
echo {0..9} | xargs -n 2 $(echo 'echo | tac')
I would except to see the following output
8 9
6 7
4 5
2 3
0 1
But instead get this
| tac 0 1
| tac 2 3
| tac 4 5
| tac 6 7
| tac 8 9
So what causes | tac
to be captured as an argument to the echo, and not as part of the command line? What is the exact mechanism and order, how the command line and command substitution is parsed, scoped and evaluated? Is it possible at all to build command lines dynamically in Linux in a metaprogramming style of way?
Edit
I know I could just use echo {0..9}| xargs -n 2 | tac
. This question is theoretical, I'm interested why the sub shell example doesn't produce the same result
$(echo 'echo | tac')
- the 1stecho
is pointless here-I
option,xargs
will always append the arguments it creates from stdin onto the END of the command-lines it executes. xargs is doing exactly what you are telling it to do. it doesn't produce the same result as in your Edit because it's a completely different command. This question is like asking "why don't I get the same output fromprintf '%s %s\n' {0..9} | tac
as I do fromprintf '| tac %s %s\n' {0..9}
?"