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
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]'