Consider such script:

echo a
echo b
echo c

It will produce 3 lines and now I can run it like this:

abc_script | real_program

real_program will get in its input those 3 files. However, there is a problem for a user, instead of just calling abc_script, she/he has to remember to redirect the output to the real_program.

So how to move this redirection to the script? Something like this (the script):

echo a | echo b | echo c | real_program

This does not work, it is only an illustration what I would like to do -- hide calling of real_program inside the script.

For the record: in my case the input consists of some file, additional extra lines. So I have:

cat $input_file
echo $extra_line

Not just a,b,c.


Like this:

( echo a
  echo b
  echo c ) | real_program

That runs the three echo commands in a subshell and pipes the subshell's output to the script.

Subshells are syntactical sugar for bash -c 'echo a; echo b; echo c' | real_program.

| improve this answer | |
  • I see, they are merged and executed as one, instead of sequentially. Thank you very much for this! For further readers, it can be put in one line, separated by semicolon. – greenoldman Jul 7 '13 at 15:21
  • I have added a bit to my answer to show how the shell performs that operation. – user26112 Jul 7 '13 at 18:56

Another way of doing this would be

echo -e "$(cat $input_file)\n$extra_line" | real_program
| improve this answer | |

A third way, which works at least with GNU bash 4.2.37 and should work with any recent bash and possibly other shells (I don't know how generally supported <() is), is to redirect input from a command.

$ echo hello > test
$ echo my > test
$ echo beautiful > test
$ cat <(cat test; echo world)

The idea is to first create the file, then launch cat redirecting its stdin from the output of the command sequence cat test; echo world. As seen in the output, that input becomes the concatenation of the output of all the input redirection commands.

An alternative way to express the same thing, which might be more portable, is to simply rewrite it as a plain old subshell pipe into a command:

(cat test; echo world) | cat

Note that the commands are executed sequentially, but their output becomes a single stream on the outer or next command's input. So while the outer cat in the above example sees no EOF or anything like that, if invoking the inner commands is expensive in some way, you will pay that price multiple times. I doubt there's any way around that.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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