2

From old habits, I'm always redirecting "from left to right", eg.

  1. cat file | bar
  2. foo | bar

I've noticed you can redirect "from right to left". However, is it possible to do this for the second form (eg. from one program to another)?

  1. bar < file
  2. bar ??? foo

Also, I'm curious if there is any conventions for when to use "from left" Vs. "from right", or if it's just matter of preference or whatever is most short or elegant.

forthrin
  • 2,289

2 Answers2

3

IIUC, you could use Bash process substitution feature to simulate second form:

$ echo foobar | grep bar
foobar
$ grep bar <(echo foobar)
foobar

Notice that for this to work command in use has to be able to accept file as a parameter - grep does it.

  • This doesn't work for IFS=$'\n' read -d '' -r -a lines <(echo a). Maybe this is exactly your disclaimer about accepting files? Is it possible to pipe from the right for this particular example? – forthrin Mar 02 '19 at 18:22
  • 1
    @forthrin read reads from standard input, so it would need to be read -d '' -r -a lines < <(echo a) – steeldriver Mar 02 '19 at 18:25
  • This makes perfect sense! Thanks for clarifying how this works. I've wondered about this for years :) – forthrin Mar 02 '19 at 18:40
  • That second example should also be grep bar < <(echo foobar) to have grep read input from its stdin, and not from a named file (even a special one named behind the scenes) – ilkkachu Mar 02 '19 at 19:12
  • @ilkkachu: indeed, and it would be even more portable. Answers that steeldriver has linked to under the question talk about that. – Arkadiusz Drabczyk Mar 02 '19 at 19:15
-1

In general you can think of commands between the pipe | as being run in a subshell.

So

foo | bar

could be thought of as

(foo) | (bar)

So this may help understand how redirection fits into things.

foo < bar | baz

would be the equivalent to

(foo < bar) | (baz)

ie the input to foo will be the file bar, and the output of that will be the input to baz.

Process substitution follows the same redirection rules:

foo <(echo bar) | baz

is the equivalent of

( foo <(echo bar) ) | (baz)