Reputation: 605
I'm trying to demonstrate the order of substitution; mainly that variable substitution, command substitution and globbing occurs in order one after the other. I executed the following command and I do not get the expected output.
bash-4.1$ a=file*
bash-4.1$ ls $(echo $($(b=$a)))
I expect the output to list all files names beginning with "file", but instead it outputs the list of all files in the directory. Any idea why?
Upvotes: 0
Views: 98
Reputation: 6577
Parameter and arithmetic expansion, and command substitution are evaluated at the same time, leftmost-innermost to right. Assignments, null and empty expansions, and redirects are all valid simple commands. The assignment is lost to the subshell, and the arguments to echo
expand to nothing. echo
outputs a newline, but the command substitution strips it, and ls
gets no args. Also, if you were expecting a=file*
to do something more than assign a literal string, pathname expansion doesn't occur in assignments.
See: http://wiki.bash-hackers.org/syntax/grammar/parser_exec
And a challenge question when you figure all that out. What will be the value of x
? (shows more expansion order and some small Bash quirks.)
declare -i x=0
x+=${x:-1} let x+=2 $((x+=4)) {x}<&$((x+=8,0))
Upvotes: 1
Reputation: 55392
The $(...)
command substitution returns the output of the command, which is blank for an assignment. So you simply end up running ls
.
Upvotes: 2