0

I want to substitute an echo command followed with | (pipe). For example,

$(echo "echo 'hello' | cat")

returns

'hello' | cat

I expect this to behave like

echo 'hello' | cat

which returns

hello

but that's not the case. Why?

PS. I'm aware of eval, and

eval $(echo "echo 'hello' | cat")

works as expected

xafizoff
  • 113

1 Answers1

3

Because syntax elements like | (or &&, or ; etc.) are recognized as the first thing of command line parsing, and are not processed again after parameters/variables are expanded.

Pretty much the only things that happen after parameter expansions, command substitutions and arithmetic expansions are word splitting and filename globbing. The outputs of expansions also don't expand again: this doesn't print 6:

$ var='$((1+2+3))'         # $((..)) not expanded here (single-quotes)
$ echo $var                # $((..)) not expanded here either
$((1+2+3))

Having another pass of parsing and expansions is exactly what eval is there for.

Related:

ilkkachu
  • 138,973
  • However, echo $(var=$((1+2+3)); echo $var) does echo a 6. –  Jun 07 '22 at 15:38
  • @done, yes, because var gets assigned the value 6, and the stuff inside the command substitution runs in a single subshell, so the variable keeps that value for the duration of that subshell, if one wants to make a convoluted command substitution like that. None of that contradicts anything I said here, though. – ilkkachu Jun 07 '22 at 19:06
  • None of that contradicts anything I said here, though. .... Well, maybe, but there is an Arithmetic expansion occurring after a command substitution has been parsed, isn't it? –  Jun 07 '22 at 20:58
  • @done, you don't need the temporary variable for that, you can do just $(echo $((a+b)) ) or $(( $(somecmd) + 3)). Nested expansions work fine. What I wrote above was about the results of the expansions being scanned for further expansions, that doesn't happen, the same way the shell doesn't scan the results of expansions for operators like |. That was what the question was about anyway. – ilkkachu Jun 07 '22 at 21:09