Piping to the command substitution of a string containing pipes

5,583

Solution 1

When you want to run variables that contain code you'll often want to use the command eval. This will expand the contents of the variable so that they can be executed.

Example

$ x='grep a | grep b'
$  echo ab | eval "$x"
ab

Using eval is often discourage though, so use caution, see this BashFAQ titled: Eval command and security issues for more examples!

References

Solution 2

Ah, I figured it out after some experimentation—use alias

$ x='grep a | grep b'
$ alias y=$x
$ echo ab | y
ab

Please do post any other ways to do this—I'd be interested in alternatives.

Share:
5,583
Andrew Cheong
Author by

Andrew Cheong

Updated on September 18, 2022

Comments

  • Andrew Cheong
    Andrew Cheong almost 2 years

    This works—

    $ x='grep a'
    $ echo ab | $x
    ab
    

    This doesn't—

    $ x='grep a | grep b'
    $ echo ab | $x
    grep: |: No such file or directory
    grep: grep: No such file or directory
    grep: b: No such file or directory
    

    It appears in the latter case, grep a | grep b is seen as a single command, i.e. grep a \| grep b.

    How do I get the second example to work without modifying x?

  • valid
    valid over 9 years
    When such an alias is run non-interactively, i.e. in a script, you need shopt -s expand_aliases before the first use of the alias - interestingly not necessarily before the alias definition.
  • Barmar
    Barmar over 4 years
    You should double-quote $x.
  • slm
    slm over 4 years
    @barmar good catch will do