Skip to content

Latest commit

History

45 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

easyproc

easyproc is a wrapper on the subprocess that provides a similar API, but attempts to reduce some of the boilerplate involved in using the module.

It's been tested with Python 3.4 and newer, though the timeout feature is broken in 3.4.

It can be installed with pip.

$ pip install easyproc

It provides the Popen class and the run class which function similarly to those in subprocess with a few differences:

  • All streams default to strings (subprocess uses bytes).
  • Error checking is turned on by default. Errors should never pass silently. Unless explicitly silenced.
  • If a string is passed as the initial argument instead of an iterable of arguments, it will be passed to shlex.split automatically.
  • stdout and stderr always behave more or less like files. In some cases, they are special objects. More later.

The module also provides a few convenience

Ok, now for a few examples.

>>>importeasyprocasep>>>ep.run('ls -lh')
total28Kdrwxr-xr-x2ninjaaronusers4.0KAug232017easyproc.egg-info-rw-r--r--1ninjaaronusers11KAug2409:51easyproc.pydrwxr-xr-x2ninjaaronusers4.0KAug2410:58__pycache__-rw-r--r--1ninjaaronusers983Aug2410:56README.rst-rw-r--r--1ninjaaronusers491Mar2612:53setup.pyCompletedProcess(args='ls -lh', returncode=0)
>>># ^ shlex.split the arguments.
...
>>>ep.run('ls foo')
ls: cannotaccess'foo': NosuchfileordirectoryTraceback (mostrecentcalllast):
File"<stdin>", line1, in<module>File"/home/ninjaaron/src/py/easyproc/easyproc.py", line207, inrunretcode=mkchecker(cmd, proc, ok_codes)()
File"/home/ninjaaron/src/py/easyproc/easyproc.py", line75, incheck_codeoutput=proc.stdout, stderr=proc.stderr)
easyproc.CalledProcessError: Command'ls foo'returnednon-zeroexitstatus2.Command'ls foo'returnednon-zeroexitstatus2.>>># crash when something doesn't work. You can either handle the>>># error or set check=False
...
>>>ep.run('ls foo', check=False)
ls: cannotaccess'foo': NosuchfileordirectoryCompletedProcess(args='ls foo', returncode=None)
>>>>>># normal concurrent stuff with Popen also works. Unicode defaults.>>>proc=ep.Popen('tr a-z A-Z', stdin=ep.PIPE, stdout=ep.PIPE)
>>>proc.communicate('foo')
('FOO', None)
>>>proc.poll()
0

So all that stuff should look pretty standard from subprocess usage. Aside from the differences mentioned above, easyproc.Popen is more or less identical to subprocess.Popen, so consult the API docs for more info.

As seen above, the run function works similarly to the subprocess equivalent. However, when you capture the output, you don't get text on the .stdout and .strerr attributes. The proper way to think of Unix command output is not blocks of text, but rather streams of lines, like a text file. (These lines may contain fields, but that isn't the concern of easyproc).

For this reason, process output is a ProcStream instance. If you use str() on it, you get the string of the process output. However, if you iterate on it, you get lines from the file (with trailing newline removed). It also has a context manager, but you won't need to access it directly if you use either of those forms patterns.

>>>importeasyprocasep>>>procstream=ep.run("ls -sh", stdout=ep.PIPE).stdout>>># ^ PIPE constant has same usage as in subprocess
...
>>>forlineinprocstream:
... print(repr(line))
...
'total 48K''4.0K easyproc.egg-info'' 12K easyproc.py'' 20K LICENSE''4.0K __pycache__''4.0K README.rst''4.0K setup.py'>>># the stream is used up after you iterate on it.
...
>>>procstream=ep.run("ls -sh", stdout=ep.PIPE).stdout>>>print(procstream)
total52K4.0Keasyproc.egg-info12Keasyproc.py20KLICENSE4.0K__pycache__8.0KREADME.rst4.0Ksetup.py>>># print calls str() implicitly.

About

a thin abstraction layer on subprocess.run() to simplify admin scripts. Python 3.5+

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages