Python 3

home

Introduction to Python

davidbpython.com




Interacting with External Processes


the operating system (OS) manages files and processes

Through interacting with the OS, we can manage files and launch other programs.







the subprocess module

This module can launch external programs from your Python script.


The subprocess module allows us to:






subprocess.call()

Executes a command and outputs to STDOUT.


for Mac/Linux, using ls:

import subprocess

subprocess.call(['ls', '-l'])      # -l means 'long listing'

for Windows, using dir:

import subprocess

subprocess.call(['dir', '/b'], shell=True)  # /b means 'bare listing'






subprocess.call(): redirecting output

The output of the called program can be directed to a file or other process.


sending output of command to a write file (and error output to STDOUT)

import subprocess
import sys

wfh = open('outfile.txt', 'w')
subprocess.call(['ls', '-l'], stdout=wfh, stderr=sys.stdout)
wfh.close()

reading the contents of a file to the input of command wc

fh = open('pyku.txt')
subprocess.call(['wc'], stdin=fh)
fh.close()






subprocess.call(): executing through the shell with shell=True

The shell means the program that runs your Command or Terminal Prompt.


import subprocess

subprocess.call('dir /b', shell=True)






subprocess.check_output()

This command executes a command and returns the output to a byte string rather than STDOUT.


(using the dir Windows command)

import subprocess

var = subprocess.check_output(["dir", "."])
var = var.decode('utf-8')
print(var)                   # prints the file listing for the current directory

(using the wc Mac/Linux command)

out = subprocess.check_output(['wc', 'pyku.txt'])
out = out.decode('utf-8')
print(out)                  #        3     15     80 pyku.txt






forking child processes with multiprocessing

forking allows a running program to execute multiple copies of itself simultaneously.







multiprocessing example

forking allows a running program to execute multiple copies of itself simultaneously.


from multiprocessing import Process
import os
import time

def info(title):                # function for a process to identify itself
    print(title)
    if hasattr(os, 'getppid'):  # only available on Unix
        print('parent process:', os.getppid())
    print('process id:', os.getpid())

def func(childnum):                # function for child to execute
    info(f'|Child Process {childnum}|')
    print('now taking on time consuming task...')
    time.sleep(3)
    print(f'{childnum}:  done')
    print()

if __name__ == '__main__':

    info('|Parent Process|')
    print(); print()
    procs = []
    for num in range(3):
        p = Process(target=func, args=(num,))
                                         # a new process object
                                         # target is function f
        p.start()                        # new process is spawned
        procs.append(p)                  # collecting list of Process objects

    for p in procs:
        p.join()                         # parent waits for child to return
    print('parent concludes')





multiprocessing output and discussion

Because multiple processes are spawned, we must imagine each one as a separately running program.



Looking closely at the output, note that all three processes executed and that the parent didn't continue until it had heard back from each of them

|Parent Process|
parent process: 92180
process id: 92316

|Child Process 0|
parent process: 92316
process id: 92318
now taking on time consuming task...
|Child Process 2|
parent process: 92316
process id: 92320
now taking on time consuming task...
|Child Process 1|
parent process: 92316
process id: 92319
now taking on time consuming task...
0:  done
2:  done
1:  done
parent concludes




[pr]