I'm looking for a alternative for | operator in bash shell for redirecting output of command as input to the next command. Is there any alternative?

something like :

command1 | command2 | command3

with alternative to:

command1 X command2 X command3

X will be use in place of |. Is it possible to avoid of using | and replace it with the actual operator of that?

  • Why do you need it? – choroba Dec 22 '14 at 16:41
  • @choroba is that important? just for avoid of using |. – αғsнιη Dec 22 '14 at 16:41
  • 3
    I'm just checking it's not an XY problem. – choroba Dec 22 '14 at 16:43
  • 3
    @KasiyA, I still don't understand the purpose of this question. Are you trying to avoid running the commands in subshells? Are you offended by the shape of the |? The 2nd question is snarky, but what problem are you trying to solve? – glenn jackman Dec 22 '14 at 16:56
  • It's still not clear. Do you want to duplicate output of the first command? Then tee with process substitution might be what you need. – muru Dec 22 '14 at 16:57
up vote 9 down vote accepted

The equivalent of command1 | command2 is command2 < <(command1)

This can be extended to three (or more) commands too.

command3 < <(command2 < <(command1))

$ lspci | grep 'Network'
 02:00.0 Network controller: Qualcomm Atheros AR9285 Wireless Network Adapter (PCI-Express) (rev 01)

$ grep 'Network' <(lspci)
 02:00.0 Network controller: Qualcomm Atheros AR9285 Wireless Network Adapter (PCI-Express) (rev 01)

$ lspci | grep 'Network' | grep -o 'controller'
 controller

$ grep -o 'controller' < <(grep 'Network' < <(lspci))
 controller

However, as Oli suggested, although this may produce the same output, it isn't technically the same as a pipe.

<(..) turns the internal command output's STDOUT into a file handler (that the command, grep in your example) opens. When you pipe, the reading command is reading directly from STDIN (which is being filled with the piped command's STDOUT). Subtle differences but can be significant with commands that only know how to read STDIN.

  • what about lspci| grep 'Network' | grep -o 'controller'? – αғsнιη Dec 22 '14 at 16:44
  • 4
    This isn't technically correct. <(..) turns the internal command output's STDOUT into a file descriptor (that the command, grep in your example) opens. When you pipe, the reading command is reading directly from STDIN (which is being filled with the piped command's STDOUT). Subtle differences but can be significant with commands that only know how to read STDIN. – Oli Dec 22 '14 at 16:45
  • edited with Oli's suggestion: cmd2 < <(cmd1) is more like it. – glenn jackman Dec 22 '14 at 16:52
  • @Oli Added your comment to the answer to highlight the difference. – Rohith Madhavan Dec 22 '14 at 17:11
  • 1
    The point is that, despite the leading ,<, this is not a redirection. <() in a command line is replaced entirely with the path to a file, a file that happens to be the stdout of the command inside the process substitution, but a path nonetheless. Whether you want to provide a path to a file or redirect from (or to it, if >()) is a separate question. That's why this is process substitution and not process redirection - like command substitution, the thing is substituted with something, a filename in one and output in the other. – muru Oct 31 '17 at 20:23

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.