A Pipe is a group of one or more command. By default all commands are lazy. It mean that they are not executed until you want a result (output).

You can always check what a Pipe will execute with print(repr(pipe))

The pipe context manager

A context manager can help you to check for some errors:

>>> from chut import cat, grep

>>> with sh.pipes(cat('fff') | grep('fff')) as p: 
...    print(p)
Traceback (most recent call last):
OSError: cat: fff: No such file or directory

Basically it checks return codes at the end of the pipe

Use predefined pipe

Define an pipe:

>>> chut = cat('README.rst') | grep('chut')

And use it:

>>> chut | sh.head('-n1')
'cat README.rst | grep chut | head -n1'

The original defined pipe stay as this (everything is copied):

>>> chut
'cat README.rst | grep chut'

You can also extract parts of the pipe using slices:

>>> chut[1:]
'grep chut'

Use python !!

You can use some python code ad the end of the pipe (and only at the end):

>>> @sh.wraps
... def check_chut(stdin):
...     for line in stdin:
...         if line.startswith(b'Chut'):
...             yield b'Chut rocks!\n'
...             break

>>> with sh.pipes(cat('README.rst') | check_chut) as cmd:
...     for line in cmd:
...         print(line)
Chut rocks!

Access binaries outside of PATH

You can use pipe to get some binaries:

>>> sh.pipe('/opt/foo/bin/bar --help')
'/opt/foo/bin/bar --help'

You can also use getitem:

>>> sh['/opt/foo/bin/bar']('--help')
'/opt/foo/bin/bar --help'

Or getattr…:

>>> getattr(sh, '/opt/bar/bin/foo')('--help')
'/opt/bar/bin/foo --help'