Search code examples
bashpipebackticks

Use of pipes in backticks


I'm trying to run a command with a pipe but receive errors:

echo abc | `echo "grep a | grep b"`
grep: |: No such file or directory
grep: grep: No such file or directory
grep: b: No such file or directory

What is wrong with the code?

Expected results is for the following command to be executed:

echo abc | grep a | grep b

With a result of

abc

Solution

  • It's not clear what you are trying to do, but here is what you are doing:

    echo "grep a | grep b"
    

    outputs the string grep a | grep b.

    This is the output from the backticks. You are using the backticks in a position where the shell wants a command, so "grep 'a' '|' 'grep' 'b'" is attempted as the command line, with all the tokens interpreted literally (I added single quotes to make this a bit clearer, hopefully) so the shell ignores the input from echo and instead attempts to look for the regular expression a in the named files. You apparently have no files named "|", "grep", or "b", so you get an error message.

    What you might want is

    echo abc | grep a | grep b
    

    which searches for "a" in the output from "echo", then searches for "b" in the output from the first grep. Because abc matches the regular expression a, the first grep succeeds, so the matching line is printed; and because it also matches the regular expression b it is printed by the final grep as well.

    To expand a bit on this, try the following:

    sh$ echo abc; echo bcd; echo xya
    abc
    bcd
    xya
    
    sh$ ( echo abc; echo bcd; echo xya ) | grep a  # print lines matching a
    abc
    xya
    
    sh$ (echo abc; echo bcd; echo xya ) | grep a | grep b  # print lines matching a and b
    abc
    

    It is not clear why you are using backticks; if this is not what you are trying to achieve, please explain in more detail what you want to accomplish.

    If you want to find lines matching either a or b, try this:

    sh$ ( echo abc; echo bcd; ) | grep '[ab]'