>>958339
It's much more tedious than a proper shell language, but it's not quite as bad as you think.
Send bytes into command, get bytes out:
>>> import subprocess as sp
>>> sp.run(['tac'], input=b'foo\nbar\n', stdout=sp.PIPE).stdout
b'bar\nfoo\n'
The same thing, but with strings:
>>> sp.run(['tac'], input='foo\nbar\n', stdout=sp.PIPE, universal_newlines=True).stdout
'bar\nfoo\n'
Chain three commands (seq 10 | sort -R | head -n 1) and read the output:
>>> seq = sp.Popen(['seq', '10'], stdout=sp.PIPE)
>>> shuf = sp.Popen(['sort', '-R'], stdin=seq.stdout, stdout=sp.PIPE)
>>> head = sp.Popen(['head', '-n', '1'], stdin=shuf.stdout, stdout=sp.PIPE)
>>> head.stdout.read()
b'3\n'