From 82f3c9a389c48548b560b9121cd4a34fa1bef8bb Mon Sep 17 00:00:00 2001 From: Fredrik Lundh Date: Tue, 12 Oct 2004 15:43:24 +0000 Subject: [PATCH] Updated the subprocess PEP to the latest version. --- pep-0324.txt | 90 +++++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 58 deletions(-) diff --git a/pep-0324.txt b/pep-0324.txt index a0240da46..59a746a50 100644 --- a/pep-0324.txt +++ b/pep-0324.txt @@ -92,16 +92,16 @@ Rationale For example, many people cannot tell the difference between popen2.popen2 and popen2.popen4 without using the documentation. - - Two small utility functions are provided: subprocess.call() and - subprocess.callv(). These aims to be an enhancement over - os.system(), while still very easy to use: + - One small utility functions is provided: subprocess.call(). It + aims to be an enhancement over os.system(), while still very + easy to use: - It does not use the Standard C function system(), which has limitations. - 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. @@ -116,17 +116,6 @@ Rationale The motivation behind the call() function is simple: Starting a 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 simple needs. Many people are using os.system() today, mainly because it provides a simple interface. Consider this example: @@ -137,10 +126,9 @@ Rationale subprocess.call(["stty", "sane", "-F", device]) - Some people feel that the list brackets are clumsy. With - callv(), they are not needed: + or, if executing through the shell: - subprocess.callv("stty", "sane", "-F", device) + subprocess.call("stty sane -F " + device, shell=True) - The "preexec" functionality makes it possible to run arbitrary code between fork and exec. One might ask why there are special @@ -177,18 +165,23 @@ Specification Arguments are: - - args should be a sequence of program arguments. The program to - execute is normally the first item in the args sequence, but can - be explicitly set by using the executable argument. - - - On UNIX: the Popen class uses os.execvp() to execute the child - program, which operates on sequences. If args is a string, it - will be converted to a sequence using the cmdline2list method. - Please note that syntax for quoting arguments is different from - a typical UNIX shell. See the documentation of the cmdline2list - method for more information. - - - On Windows: the Popen class uses CreateProcess() to execute the + - args should be a string, or a sequence of program arguments. + The program to execute is normally the first item in the args + sequence or string, but can be explicitly set by using the + executable argument. + + On UNIX, with shell=False (default): In this case, the Popen + class uses os.execvp() to execute the child program. args + should normally be a sequence. A string will be treated as a + sequence with the string as the only item (the program to + execute). + + 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 sequence, it will be converted to a string using the list2cmdline method. Please note that not all MS Windows @@ -221,11 +214,7 @@ Specification will be closed before the child process is executed. - If shell is true, the specified command will be executed through - the shell. Note: When executing through the shell on UNIX - 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. + the shell. - If cwd is not None, the current directory will be changed to cwd before the child is executed. @@ -261,21 +250,6 @@ Specification 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 ---------- @@ -389,7 +363,7 @@ Replacing older functions with the subprocess module sts = os.system("mycmd" + " myarg") ==> - p = Popen(["mycmd" + " myarg"], shell=True) + p = Popen("mycmd" + " myarg", shell=True) sts = os.waitpid(p.pid, 0) Note: @@ -402,7 +376,7 @@ Replacing older functions with the subprocess module A more real-world example would look like this: try: - retcode = callv("mycmd", "myarg") + retcode = call("mycmd" + " myarg", shell=True) if retcode < 0: print >>sys.stderr, "Child was terminated by signal", -retcode else: @@ -425,7 +399,7 @@ Replacing older functions with the subprocess module retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg") ==> - retcode = callv("/bin/mycmd", "myarg") + retcode = call(["/bin/mycmd", "myarg"]) Vector example: @@ -447,16 +421,16 @@ Replacing older functions with the subprocess module 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 = 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) ==> - p = Popen([cmd], shell=True, bufsize=bufsize, + p = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE, stdout=PIPE, close_fds=True) (child_stdin, child_stdout) = (p.stdin, p.stdout) @@ -465,7 +439,7 @@ Replacing older functions with the subprocess module child_stdout, 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) (child_stdin, child_stdout, @@ -474,7 +448,7 @@ Replacing older functions with the subprocess module (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) (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)