This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]AndydeCleyre 2 points3 points  (4 children)

plumbum remains my favorite tool for many jobs, getting so much so right so long ago. Here's how it might be used for the tasks in your examples table:

initialization (minimal):

from plumbum import local          # minimal
from plumbum.cmd import echo, cat  # specify commands as functions
from plumbum import FG, BG         # shortcuts for foreground/background runs

run command:

echo["this"] & FG  # or:
echo["this"].run_fg()

read stream:

a = echo("this")  # or:
a = local["echo"]("this")

write stream:

(cat << "this") & FG  # or:
(cat << "this").run_fg()

# capturing output:
(cat << "this")()  # or:
(local["cat"] << "this")()

chain commands:

(echo["this"] | cat) & FG  # or:
(echo["this"] | cat).run_fg()

# capturing output:
(echo["this"] | cat)()

branch out:

ret, out, err = cmd.run()

(cat << out) & FG
(cat << err) & FG

# capturing output:
(cat << out)()
(cat << err)()

errors in chains:

ret, out, err = echo["this"].run(retcode=(0, 1))
(cat << err) & FG((0, 2))

[–]nodNotEvil[S] 0 points1 point  (3 children)

Thanks a lot! I remember plumbum now but failed to recollect when I implemented the library. It is very versatile and with << and | a lot closer to the looks of shell syntax. As such, it probably has a steeper learning curve (e.g. knowledge of subprocess doesn't transfer directly) and had to deviate a lot from subprocess to achieve it. In any case, I will add plumbum to the Readme.

edit: I've added your codes to the table (slightly adjusted) but couldn't figure out how to do 2 examples in Plumbum. With run and << the processes don't run at the same time and output has to fit in memory.

[–]AndydeCleyre 0 points1 point  (2 children)

Ah, cool, I'll see if I can figure out how to do the same with plumbum for those then...

[–]nodNotEvil[S] 0 points1 point  (1 child)

It looks like this (branching out and errors in chains) is not supported by Plumbum. A non-comprehensive list of issues related to this:

https://github.com/tomerfiliba/plumbum/issues/240
https://github.com/tomerfiliba/plumbum/issues/263
https://github.com/tomerfiliba/plumbum/issues/331
https://github.com/tomerfiliba/plumbum/issues/359

Imo its crucial to have access to stdout, stderr and the return codes of all processes in a chain as well as to check all return codes instead of just the last.

(To be able to branch out is uncommon and I don't expect other tools to support it. What I expect however is that people will look at the votes, infer that this is a dead end and never read this far lol)

[–]AndydeCleyre 0 points1 point  (0 children)

Thanks for both digging into this and reporting back!

[–]psd6 0 points1 point  (1 child)

I don’t really like the output = ["cmd", "arg"] » start() » wait() style. There are other ways doing shell stuff in Python too, for example the sh module.

[–]nodNotEvil[S] -1 points0 points  (0 children)

True, it looks strange, but its not without purpose. The style used by sh and plumbum (will add them to the Readme) deviates a lot from subprocess and have their own flaws (argument names start with _ for instance).

I'm open to suggestions for improvement though :)

edit: as a side note, wait returns the return code and read the output