Bash – backticks inside brace expansion

bashbrace-expansioncommand-substitution

I'm trying to list the files of httpd processes, and I tried this:

ls -l /proc/{`pidof httpd | tr ' ' ','`}/
ls: cannot access /proc/{{28493,28492,28491,28490,28489,28488,28487,28486,28483}}/: No such file or directory

But if I put the PID inside the brackets myself, it works:

ls -l /proc/{28493,28492,28491,28490,28489,28488,28487,28486,28483}/ | head -6
/proc/28483/:
total 0
dr-xr-xr-x 2 root root 0 Jan 30 11:18 attr
-rw-r--r-- 1 root root 0 Jan 30 11:18 autogroup
-r-------- 1 root root 0 Jan 30 11:18 auxv

I believe in the first case, the shell is considering the backtick output as a single argument, and is not expanding. So I'm wondering, is there a way of making it see as a list to be expanded? I know I could do this with a for loop, or in many other ways. I'm particularly interested in learning more about backticks and brace expansions, assuming it is possible to do it.

Best Answer

The order of evaluation in bash is such that brace expansion is done first, and command substitutions are not handled until later.

Here's the order in which things are done by bash:

  1. brace expansion,
  2. tilde expansion,
  3. parameter and variable expansion,
  4. command substitution,
  5. arithmetic expansion,
  6. word splitting,
  7. pathname expansion.

Alternative solution:

for pid in $( pidof httpd ); do ls -l /proc/"$pid"; done
Related Question