EasyProcess is an easy to use python subprocess interface.
- Links:
- home: https://github.com/ponty/EasyProcess
- documentation: http://EasyProcess.readthedocs.org
- PYPI: https://pypi.python.org/pypi/EasyProcess
- Features:
- layer on top of subprocess module
- easy to start, stop programs
- easy to get standard output/error, return code of programs
- command can be list or string
- logging
- timeout
- unit-tests
- cross-platform, development on linux
- global config file with program aliases
- shell is not supported
- pipes are not supported
- stdout/stderr is set only after the subprocess has finished
- stop() does not kill whole subprocess tree
- unicode support
- supported python versions: 2.6, 2.7, 3.3, 3.4, 3.5
- Method chaining
- Similar projects:
- execute (http://pypi.python.org/pypi/execute)
- commandwrapper (http://pypi.python.org/pypi/commandwrapper)
- extcmd (http://pypi.python.org/pypi/extcmd)
- sh (https://github.com/amoffat/sh)
- envoy (https://github.com/kennethreitz/envoy)
- plumbum (https://github.com/tomerfiliba/plumbum)
>>> from easyprocess import EasyProcess >>> EasyProcess('python --version').call().stderr u'Python 2.6.6'
install pip
install the program:
# as root pip install EasyProcess
sudo apt-get install python-pip sudo pip install EasyProcess
# as root pip uninstall EasyProcess
Example program:
#-- include('examples/hello.py')--# from easyprocess import EasyProcess import sys s = EasyProcess([sys.executable, '-c', 'print "hello"']).call().stdout print(s) #-#
Output:
#-- sh('python -m easyprocess.examples.hello')--# hello #-#
The command can be a string list or a concatenated string:
#-- include('examples/cmd.py')--# from easyprocess import EasyProcess print('-- Run program, wait for it to complete, get stdout (command is string):') s=EasyProcess('python -c "print 3"').call().stdout print(s) print('-- Run program, wait for it to complete, get stdout (command is list):') s=EasyProcess(['python','-c','print 3']).call().stdout print(s) print('-- Run program, wait for it to complete, get stderr:') s=EasyProcess('python --version').call().stderr print(s) print('-- Run program, wait for it to complete, get return code:') s=EasyProcess('python --version').call().return_code print(s) print('-- Run program, wait 1 second, stop it, get stdout:') s=EasyProcess('ping localhost').start().sleep(1).stop().stdout print(s) #-#
Output:
#-- sh('python -m easyprocess.examples.cmd')--# -- Run program, wait for it to complete, get stdout (command is string): 3 -- Run program, wait for it to complete, get stdout (command is list): 3 -- Run program, wait for it to complete, get stderr: Python 2.7.6 -- Run program, wait for it to complete, get return code: 0 -- Run program, wait 1 second, stop it, get stdout: PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.017 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.034 ms #-#
Shell commands are not supported.
Warning
echo
is a shell command on Windows (there is no echo.exe),
but it is a program on Linux
:attr:`EasyProcess.return_code` is None until :func:`EasyProcess.stop` or :func:`EasyProcess.wait` is called.
By using :keyword:`with` statement the process is started and stopped automatically:
from easyprocess import EasyProcess with EasyProcess('ping 127.0.0.1') as proc: # start() # communicate with proc pass # stopped
Equivalent with:
from easyprocess import EasyProcess proc = EasyProcess('ping 127.0.0.1').start() try: # communicate with proc pass finally: proc.stop()
This was implemented with "daemon thread".
"The entire Python program exits when only daemon threads are left." http://docs.python.org/library/threading.html:
#-- include('examples/timeout.py')--# from easyprocess import EasyProcess s = EasyProcess('ping localhost').call(timeout=2).stdout print(s) #-#
Output:
#-- sh('python -m easyprocess.examples.timeout')--# PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.018 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.037 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.025 ms #-#
Replacing os.system:
retcode = os.system("ls -l") ==> p = EasyProcess("ls -l").call() retcode = p.return_code print p.stdout
Replacing subprocess.call:
retcode = subprocess.call(["ls", "-l"]) ==> p = EasyProcess(["ls", "-l"]).call() retcode = p.return_code print p.stdout