1EasyProcess is an easy to use python subprocess interface.
2
3Links:
4 * home: https://github.com/ponty/EasyProcess
5 * documentation: http://EasyProcess.readthedocs.org
6 * PYPI: https://pypi.python.org/pypi/EasyProcess
7
8|Travis| |Coveralls| |Latest Version| |Supported Python versions| |License| |Downloads| |Code Health| |Documentation|
9
10Features:
11 - layer on top of subprocess_ module
12 - easy to start, stop programs
13 - easy to get standard output/error, return code of programs
14 - command can be list or string
15 - logging
16 - timeout
17 - unit-tests
18 - cross-platform, development on linux
19 - global config file with program aliases
20 - shell is not supported
21 - pipes are not supported
22 - stdout/stderr is set only after the subprocess has finished
23 - stop() does not kill whole subprocess tree
24 - unicode support
25 - supported python versions: 2.6, 2.7, 3.3, 3.4, 3.5
26 - Method chaining_
27
28Similar projects:
29 * execute (http://pypi.python.org/pypi/execute)
30 * commandwrapper (http://pypi.python.org/pypi/commandwrapper)
31 * extcmd (http://pypi.python.org/pypi/extcmd)
32 * sh (https://github.com/amoffat/sh)
33 * envoy (https://github.com/kennethreitz/envoy)
34 * plumbum (https://github.com/tomerfiliba/plumbum)
35
36Basic usage
37===========
38
39    >>> from easyprocess import EasyProcess
40    >>> EasyProcess('python --version').call().stderr
41    u'Python 2.6.6'
42
43Installation
44============
45
46General
47-------
48
49 * install pip_
50 * install the program::
51
52    # as root
53    pip install EasyProcess
54
55Ubuntu 14.04
56------------
57::
58
59    sudo apt-get install python-pip
60    sudo pip install EasyProcess
61
62Uninstall
63---------
64::
65
66    # as root
67    pip uninstall EasyProcess
68
69
70Usage
71=====
72
73Simple example
74--------------
75
76Example program::
77
78  #-- include('examples/hello.py')--#
79  from easyprocess import EasyProcess
80  import sys
81
82  s = EasyProcess([sys.executable, '-c', 'print "hello"']).call().stdout
83  print(s)
84  #-#
85
86Output::
87
88  #-- sh('python -m easyprocess.examples.hello')--#
89  hello
90  #-#
91
92
93General
94-------
95
96The command can be a string list or a concatenated string::
97
98  #-- include('examples/cmd.py')--#
99  from easyprocess import EasyProcess
100
101  print('-- Run program, wait for it to complete, get stdout (command is string):')
102  s=EasyProcess('python -c "print 3"').call().stdout
103  print(s)
104
105  print('-- Run program, wait for it to complete, get stdout (command is list):')
106  s=EasyProcess(['python','-c','print 3']).call().stdout
107  print(s)
108
109  print('-- Run program, wait for it to complete, get stderr:')
110  s=EasyProcess('python --version').call().stderr
111  print(s)
112
113  print('-- Run program, wait for it to complete, get return code:')
114  s=EasyProcess('python --version').call().return_code
115  print(s)
116
117  print('-- Run program, wait 1 second, stop it, get stdout:')
118  s=EasyProcess('ping localhost').start().sleep(1).stop().stdout
119  print(s)
120
121  #-#
122
123Output::
124
125  #-- sh('python -m easyprocess.examples.cmd')--#
126  -- Run program, wait for it to complete, get stdout (command is string):
127  3
128  -- Run program, wait for it to complete, get stdout (command is list):
129  3
130  -- Run program, wait for it to complete, get stderr:
131  Python 2.7.6
132  -- Run program, wait for it to complete, get return code:
133  0
134  -- Run program, wait 1 second, stop it, get stdout:
135  PING localhost (127.0.0.1) 56(84) bytes of data.
136  64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.017 ms
137  64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.034 ms
138  #-#
139
140Shell commands
141--------------
142
143Shell commands are not supported.
144
145.. warning::
146
147  ``echo`` is a shell command on Windows (there is no echo.exe),
148  but it is a program on Linux
149
150return_code
151-----------
152
153:attr:`EasyProcess.return_code` is None until
154:func:`EasyProcess.stop` or :func:`EasyProcess.wait`
155is called.
156
157With
158----
159
160By using :keyword:`with` statement the process is started
161and stopped automatically::
162
163    from easyprocess import EasyProcess
164    with EasyProcess('ping 127.0.0.1') as proc: # start()
165        # communicate with proc
166        pass
167    # stopped
168
169Equivalent with::
170
171    from easyprocess import EasyProcess
172    proc = EasyProcess('ping 127.0.0.1').start()
173    try:
174        # communicate with proc
175        pass
176    finally:
177        proc.stop()
178
179
180Timeout
181-------
182
183This was implemented with "daemon thread".
184
185"The entire Python program exits when only daemon threads are left."
186http://docs.python.org/library/threading.html::
187
188  #-- include('examples/timeout.py')--#
189  from easyprocess import EasyProcess
190
191  s = EasyProcess('ping localhost').call(timeout=2).stdout
192  print(s)
193  #-#
194
195Output::
196
197  #-- sh('python -m easyprocess.examples.timeout')--#
198  PING localhost (127.0.0.1) 56(84) bytes of data.
199  64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.018 ms
200  64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.037 ms
201  64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.025 ms
202  #-#
203
204
205Replacing existing functions
206----------------------------
207
208Replacing os.system::
209
210    retcode = os.system("ls -l")
211    ==>
212    p = EasyProcess("ls -l").call()
213    retcode = p.return_code
214    print p.stdout
215
216Replacing subprocess.call::
217
218    retcode = subprocess.call(["ls", "-l"])
219    ==>
220    p = EasyProcess(["ls", "-l"]).call()
221    retcode = p.return_code
222    print p.stdout
223
224
225.. _pip: http://pip.openplans.org/
226.. _subprocess: http://docs.python.org/library/subprocess.html
227.. _chaining: https://en.wikipedia.org/wiki/Method_chaining#Python
228
229.. |Travis| image:: http://img.shields.io/travis/ponty/EasyProcess.svg
230   :target: https://travis-ci.org/ponty/EasyProcess/
231.. |Coveralls| image:: http://img.shields.io/coveralls/ponty/EasyProcess/master.svg
232   :target: https://coveralls.io/r/ponty/EasyProcess/
233.. |Latest Version| image:: https://img.shields.io/pypi/v/EasyProcess.svg
234   :target: https://pypi.python.org/pypi/EasyProcess/
235.. |Supported Python versions| image:: https://img.shields.io/pypi/pyversions/EasyProcess.svg
236   :target: https://pypi.python.org/pypi/EasyProcess/
237.. |License| image:: https://img.shields.io/pypi/l/EasyProcess.svg
238   :target: https://pypi.python.org/pypi/EasyProcess/
239.. |Downloads| image:: https://img.shields.io/pypi/dm/EasyProcess.svg
240   :target: https://pypi.python.org/pypi/EasyProcess/
241.. |Code Health| image:: https://landscape.io/github/ponty/EasyProcess/master/landscape.svg?style=flat
242   :target: https://landscape.io/github/ponty/EasyProcess/master
243.. |Documentation| image:: https://readthedocs.org/projects/pyscreenshot/badge/?version=latest
244   :target: http://easyprocess.readthedocs.org
245
246
247
248
249
250
251
252