4.3 Pipelines

As with most other shells, Eshell supports pipelines to pass the output of one command the input of the next command. You can send the standard output of one command to the standard input of another using the | operator. For example,

~ $ echo hello | rev
olleh

To send both the standard output and standard error of a command to another command’s input, you can use the |& operator.

4.3.1 Running Shell Pipelines Natively

When constructing shell pipelines that will move a lot of data, it is a good idea to bypass Eshell’s own pipelining support and use the operating system shell’s instead. This is especially relevant when executing commands on a remote machine using Eshell’s Tramp integration: using the remote shell’s pipelining avoids copying the data which will flow through the pipeline to local Emacs buffers and then right back again.

Eshell recognizes a special syntax to make it easier to convert pipelines so as to bypass Eshell’s pipelining. Prefixing at least one |, < or > with an asterisk marks a command as intended for the operating system shell. To make it harder to invoke this functionality accidentally, it is also required that the asterisk be preceded by whitespace or located at the start of input. For example,

 cat *.ogg *| my-cool-decoder >file

Executing this command will not copy all the data in the *.ogg files, nor the decoded data, into Emacs buffers, as would normally happen.

The command is interpreted as extending up to the next | character which is not preceded by an unescaped asterisk following whitespace, or the end of the input if there is no such character. Thus, all < and > redirections occurring before the next asterisk-unprefixed | are implicitly prefixed with (whitespace and) asterisks. An exception is that Eshell-specific redirects right at the end of the command are excluded. This allows input like this:

 foo *| baz >#<buffer quux>

which is equivalent to input like this:

 sh -c "foo | baz" >#<buffer quux>