Consider the following command:
echo <(cat /etc/{motd,passwd})
(you can replace "echo" with any command that takes one file as argument and cannot take it as stdin)
It's obvious that the goal is to expand this to:
echo <(cat /etc/motd /etc/passwd)
Then to:
echo /dev/fd/63
However, it doesn't work like this:
$ echo <(cat /etc/{motd,passwd})
++ cat /etc/motd
++ cat /etc/passwd
+ echo /dev/fd/63 /dev/fd/62
/dev/fd/63 /dev/fd/62
But bash doesn't work like this. Brace expansion is done first, but inside parameters of the command (that is, <(cat /etc/{motd,passwd})
) not words. So when <(cat /etc/{motd,passwd})
is expanded, the prefix is <(cat /etc/
, the suffix is ")", so it's expanded to <(cat /etc/motd) <(cat /etc/passwd)
.
After reporting a bug about that, Chet Ramey gave me the correct way to reach the initial goal:
cat <(eval cat /etc/\{passwd,motd})