Updated the subprocess PEP to the latest version.

This commit is contained in:
Fredrik Lundh 2004-10-12 15:43:24 +00:00
parent bf4a5c7ebb
commit 82f3c9a389
1 changed files with 32 additions and 58 deletions

View File

@ -92,16 +92,16 @@ Rationale
For example, many people cannot tell the difference between For example, many people cannot tell the difference between
popen2.popen2 and popen2.popen4 without using the documentation. popen2.popen2 and popen2.popen4 without using the documentation.
- Two small utility functions are provided: subprocess.call() and - One small utility functions is provided: subprocess.call(). It
subprocess.callv(). These aims to be an enhancement over aims to be an enhancement over os.system(), while still very
os.system(), while still very easy to use: easy to use:
- It does not use the Standard C function system(), which has - It does not use the Standard C function system(), which has
limitations. limitations.
- It does not call the shell implicitly. - It does not call the shell implicitly.
- No need for quoting; using a variable argument list. - No need for quoting; using an argument list.
- The return value is easier to work with. - The return value is easier to work with.
@ -116,17 +116,6 @@ Rationale
The motivation behind the call() function is simple: Starting a The motivation behind the call() function is simple: Starting a
process and wait for it to finish is a common task. process and wait for it to finish is a common task.
The callv() function is identical to call(), except that each
non-keyword argument is treated as a program argument. This
gives a slightly nicer syntax. The drawback is that callv()
does not allow specifying the program and it's arguments as a
whitespace-separated string: The entire (first) string would be
interpreted as the executable. The implementation of callv() is
also very simple:
def callv(*args, **kwargs):
return Popen(args, **kwargs).wait()
While Popen supports a wide range of options, many users have While Popen supports a wide range of options, many users have
simple needs. Many people are using os.system() today, mainly simple needs. Many people are using os.system() today, mainly
because it provides a simple interface. Consider this example: because it provides a simple interface. Consider this example:
@ -137,10 +126,9 @@ Rationale
subprocess.call(["stty", "sane", "-F", device]) subprocess.call(["stty", "sane", "-F", device])
Some people feel that the list brackets are clumsy. With or, if executing through the shell:
callv(), they are not needed:
subprocess.callv("stty", "sane", "-F", device) subprocess.call("stty sane -F " + device, shell=True)
- The "preexec" functionality makes it possible to run arbitrary - The "preexec" functionality makes it possible to run arbitrary
code between fork and exec. One might ask why there are special code between fork and exec. One might ask why there are special
@ -177,18 +165,23 @@ Specification
Arguments are: Arguments are:
- args should be a sequence of program arguments. The program to - args should be a string, or a sequence of program arguments.
execute is normally the first item in the args sequence, but can The program to execute is normally the first item in the args
be explicitly set by using the executable argument. sequence or string, but can be explicitly set by using the
executable argument.
- On UNIX: the Popen class uses os.execvp() to execute the child On UNIX, with shell=False (default): In this case, the Popen
program, which operates on sequences. If args is a string, it class uses os.execvp() to execute the child program. args
will be converted to a sequence using the cmdline2list method. should normally be a sequence. A string will be treated as a
Please note that syntax for quoting arguments is different from sequence with the string as the only item (the program to
a typical UNIX shell. See the documentation of the cmdline2list execute).
method for more information.
- On Windows: the Popen class uses CreateProcess() to execute the On UNIX, with shell=True: If args is a string, it specifies the
command string to execute through the shell. If args is a
sequence, the first item specifies the command string, and any
additional items will be treated as additional shell arguments.
On Windows: the Popen class uses CreateProcess() to execute the
child program, which operates on strings. If args is a child program, which operates on strings. If args is a
sequence, it will be converted to a string using the sequence, it will be converted to a string using the
list2cmdline method. Please note that not all MS Windows list2cmdline method. Please note that not all MS Windows
@ -221,11 +214,7 @@ Specification
will be closed before the child process is executed. will be closed before the child process is executed.
- If shell is true, the specified command will be executed through - If shell is true, the specified command will be executed through
the shell. Note: When executing through the shell on UNIX the shell.
systems and the args argument is a sequence, only the first
element in the sequence will be passed as a command string to
the shell. The remaining arguments can be used to specify
additional shell options.
- If cwd is not None, the current directory will be changed to cwd - If cwd is not None, the current directory will be changed to cwd
before the child is executed. before the child is executed.
@ -261,21 +250,6 @@ Specification
retcode = call(["ls", "-l"]) retcode = call(["ls", "-l"])
- callv(*args, **kwargs):
Run command with arguments. Wait for command to complete,
then return the returncode attribute.
This function is identical to call(), except that each
non-keyword argument is treated as a program argument.
Example:
retcode = callv("ls", "-l")
This is equivalent to:
retcode = call(["ls", "-l"])
Exceptions Exceptions
---------- ----------
@ -389,7 +363,7 @@ Replacing older functions with the subprocess module
sts = os.system("mycmd" + " myarg") sts = os.system("mycmd" + " myarg")
==> ==>
p = Popen(["mycmd" + " myarg"], shell=True) p = Popen("mycmd" + " myarg", shell=True)
sts = os.waitpid(p.pid, 0) sts = os.waitpid(p.pid, 0)
Note: Note:
@ -402,7 +376,7 @@ Replacing older functions with the subprocess module
A more real-world example would look like this: A more real-world example would look like this:
try: try:
retcode = callv("mycmd", "myarg") retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0: if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode print >>sys.stderr, "Child was terminated by signal", -retcode
else: else:
@ -425,7 +399,7 @@ Replacing older functions with the subprocess module
retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg") retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==> ==>
retcode = callv("/bin/mycmd", "myarg") retcode = call(["/bin/mycmd", "myarg"])
Vector example: Vector example:
@ -447,16 +421,16 @@ Replacing older functions with the subprocess module
pipe = os.popen(cmd, mode='r', bufsize) pipe = os.popen(cmd, mode='r', bufsize)
==> ==>
pipe = Popen([cmd], shell=True, bufsize=bufsize, stdout=PIPE).stdout pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
pipe = os.popen(cmd, mode='w', bufsize) pipe = os.popen(cmd, mode='w', bufsize)
==> ==>
pipe = Popen([cmd], shell=True, bufsize=bufsize, stdin=PIPE).stdin pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize) (child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==> ==>
p = Popen([cmd], shell=True, bufsize=bufsize, p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True) stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout) (child_stdin, child_stdout) = (p.stdin, p.stdout)
@ -465,7 +439,7 @@ Replacing older functions with the subprocess module
child_stdout, child_stdout,
child_stderr) = os.popen3(cmd, mode, bufsize) child_stderr) = os.popen3(cmd, mode, bufsize)
==> ==>
p = Popen([cmd], shell=True, bufsize=bufsize, p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin, (child_stdin,
child_stdout, child_stdout,
@ -474,7 +448,7 @@ Replacing older functions with the subprocess module
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize) (child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==> ==>
p = Popen([cmd], shell=True, bufsize=bufsize, p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout) (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)