Sunday, December 30, 2018

The subprocess module



The sub-process module allows us to spawn processes, connect to their input/output/error pipes, and obtain their return codes. sub-process should be used for accessing system commands. With sub-process you can suppress the output, which is very handy when you want to run a system call but are not interested about the standard output. 

The subprocess.call method()

The subprocess.call method is an easy to way to invoke an external program. It works on all platforms.  It also gives you a way to cleanly integrate shell commands into your scripts while managing input/output in a standard way. We can use sub-process.call return codes to determine the success of the command. 

Every process will return an exit code and you can do something with your script based on that code. If the return code is anything else than zero, it means that an error occurred. Let's see an example which uses subprocess to launch a more powerful compressor, PAQ. A PAQ executable is available in downloadable archives on the Internet. We will use a PAQ8 implementation. The same command compresses, and expands, a file. See the code below:

import subprocess

exe = r"C:\fp8_v2.exe"
source = r"C:\profiles\file.bin"

subprocess.call(exe + " " + source)

When we run the program we get the following output:

Creating archive C:\profiles\file.bin.fp8 with 1 file(s)...

File list (18 bytes)
Compressed from 18 to 22 bytes.

1/1  Filename: C:/profiles/file.bin (3836648 bytes)
Block segmentation:
 0           | default   |     28016 bytes [0 - 28015]
 1           | jpeg      |      8917 bytes [28016 - 36932]
 2           | default   |   3799715 bytes [36933 - 3836647]
Compressed from 3836648 to 114930 bytes.

Total 3836648 bytes compressed to 114958 bytes.
Time 44.26 sec, used 180892539 bytes of memory

Close this window or press ENTER to continue...

The subprocess.Popen()

The sub process module enables you to start new applications from your Python program. We can start a process in Python using the Popen function call. To start a command prompt from a program we can pass the program’s filename to subprocess.Popen() as shown below:

import subprocess

subprocess.Popen('C:\Windows\System32\cmd.exe')

When we run this program the command prompt will be open in the ouput window as shown below:

------------------
(program exited with code: 0)

Press any key to continue . . . Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

F:\Python_Code\examples>

The launched program is not run in the same thread as our Python program. The return value is a Popen object, which has two useful methods: poll() and wait().

The poll() method will return None if the process is still running at the time poll() is called. If the program has terminated, it will return the process’s integer exit code. An exit code is used to indicate whether the process terminated without errors (an exit code of 0) or whether an error caused the process to terminate (a nonzero exit code—generally 1, but it may vary depending on the program).

The wait() method will block until the launched process has terminated. This is helpful if we want our program to pause until the user finishes with the other program. The return value of wait() is the process’s integer exit code. See an example below:

import subprocess

cp = subprocess.Popen('C:\Windows\System32\dvdplay.exe')
print(cp.poll()==None)
print(cp.wait())
print(cp.poll())

Here we open a dvdplay process and while it is running we check if poll() returns none which it does as the process is still running. Next we close the dvdplay program and call wait() on the terminated
process. Both the wait() and poll() now return 0, indicating that the process terminated without errors. The output of the program is shown below:

True
0
0

------------------
(program exited with code: 0)

Press any key to continue . . .

The Python documentation recommends the use of Popen in advanced cases, when other methods such like subprocess.call cannot fulfill our needs.

We can pass command line arguments to processes you create with Popen(). To do so, you pass a list as the sole argument to Popen(). The first string in this list will be the executable filename of the program you want to launch; all the subsequent strings will be the command line arguments to pass to
the program when it starts. In effect, this list will be the value of sys.argv for the launched program.
Most applications with a graphical user interface (GUI) don’t use command line arguments as extensively as command line–based or terminal based programs do. But most GUI applications will accept a single argument for a file that the applications will immediately open when they start. Let's try to open a text file in our program directory using the Popen() which will not only launch Notepad application but also have it immediately open the desired text file. See the code below:

import subprocess

subprocess.Popen(['C:\\Windows\\notepad.exe', 'C:\\Python_Code\\examples\\cities.txt'])

When we run this program the cities.txt file opens in notepad.

It is also possible to launch a Python script from Python just like any other application. We just have to pass the python.exe executable to Popen() and the filename of the .py script we want to run as its argument. See the example below:

import subprocess

subprocess.Popen([r'C:\Users\Python\AppData\Local\Programs\Python\Python36\python.exe', 'complete_name.py'])

Pass Popen() a list containing a string of the Python executable’s path and a string of the script’s filename. Unlike importing the Python program as a module, when your Python program launches another Python program, the two are run in separate processes and will not be able to share each other’s variables. To handle separators in paths better, we can use raw string literals with the "r" prefix.

Each operating system has a program that performs the equivalent of double-clicking a document file to open it. On Windows, this is the start program. Python can also open files this way with Popen(). See the program below:

import subprocess

obj = open('cities.txt','w')
obj.write('Jabalpur')

subprocess.Popen(['start', 'cities.txt'], shell=True)


Here we write Jabalpur to a new cities.txt file. Then we call Popen(),passing it a list containing the program name (in this example, 'start' for Windows) and the filename. We also pass the shell=True keyword argument, which is needed only on Windows. The operating system knows all of the file associations and can figure out that it should launch, say, Notepad.exe to handle the cities.txt file. When we run this program a new new cities.txt file is created by the program and the program writes Jabalpur to the file and opens it in notepad.

With this I am ending today's post, Until we meet next keep practicing and learning Python as Python is easy to learn!
Share:

0 comments:

Post a Comment