I've defined an alias like:

alias xyz='command1; command2'

I want to pipe output of another command pqr to command2 like:

pqr | xyz -f -

Is it possible? How can I achieve that?

3 Answers 3


Using an alias is generally not good practice in non-interactive shell scripts ( BashFAQ/080 ). The way you have the alias defined in your OP, only the first commands reads from the standard input, because ; terminates your standard input from going beyond your first command.

One possible way is to do a command grouping using {..}, so that any re-directions apply to the entire set of commands within the group. You can still retain your alias definition and do

alias xyz='{ command1; command2; }'

In which case your comamnd1 unnecessarily gets a copy of the standard input. You can close it by doing

alias xyz='{ command1 < /dev/null ; command2 - ; }'

Or use functions to define your commands within.

xyz() {
    command1; command2

If your shell is bash or zsh that supports process substitution you can just define command2 to receive stdin content as positional arguments. Re-define your function as

xyz() {
    command2 "$@"

and then call your command (pqr) as

xyz < <(pqr)

A simple demonstration of the above,

zoo() { date; sed 's/foo/boo/' "$@"; }
zoo < <(echo food)                     #(or) zoo <<<"food"
Mon Nov 25 02:44:49 EST 2019
  • 2
    Your first couple of aliases would not wok with pqr | xyz -f - as the -f - would end up on the outside of the { ...; } compound command. Also, the - may not be a valid thing to give to command2 (your second alias). Your second function look ok, if you pass /dev/null into command1, but you would call it as xyz -f - to emulate what the user is doing.
    – Kusalananda
    Nov 25, 2019 at 8:33

I suggest you'll try the xargs approach, i.e.:

alias xyz='command1; command2 | xargs pqr'

That is equivalent for running pqr with command2 as its input argument

  • The user want to pipe the output of prq into command2 -f -. They additionally don't want to make prq or -f - part of the alias.
    – Kusalananda
    Nov 25, 2019 at 8:28

To pass something into the standard input of command2 in the command list

command1; command2

you would have to make sure that command1 does not read from standard input. This could be done by redirecting the standard input from /dev/null into command1:

command1 </dev/null; command2

This leaves you with the alias

alias xyz='command1 </dev/null; command2`

which you would not be able to call with

pqr | xyz -f -

as that would be equivalent to

pqr | command1 </dev/null; command2 -f -

which is the same as

pqr | command1 </dev/null
command2 -f -

Instead, define xyz as a shell function:

xyz () {
    command1 </dev/null
    command2 "$@"

Here, command2 would get both the standard input of the function as well as any command line arguments given to the function.

You would now be able to use this as in the pipeline pqr | xyz -f -.

If (and only if) the -f - arguments that you pass to command2 is to say "read from standard input" (with - denoting standard input), then you could instead of - pass a process substitution to xyz, if your shell supports it:

xyz -f <(pqr)

With the above function, this would be the same as doing

command1 </dev/null
command2 -f <(pqr)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .