Labels

Aws (32) MySQL (20) Aurora (12) Rds (7) DynamoDB (6) Cloudformation (4) Python3 (4) Unix (3) MongoDB (1)

Friday, 8 December 2017

Python3 - Subprocess, Runs bash commands in a Python script

Subprocess for running Bash command on Shell

Subprocess module (newer) (After 3.5.3) The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. (Current version 3.4.3) Uses .call

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
I.E. subprocess.call(["ls","-l"]) proc = subprocess.Popen(['ls','-s','-l'])
There are two modes to specify args for call method.
  1. subprocess.call(["ls","-l"])
    • The first arg in the list is the command
    • The other values in the list are treads as argument of the first value, as [argv]
  2. subprocess.call("ls -l", shell=True)
    • The first string argument is passed to shell program. It is usual /bin/bash
I.E.
subprocess.check_output(['ls', '|', 'wc', '-l'])   DOESN'T WORK
subprocess.call('ls | wc -l', shell=True)          WORKS

Getting the return code (aka exist status)

The call and check_call functions, returns the exit status
proc = subprocess.Popen('sleep 1',shell=True)
The moment the Popen class is called, the command starts running. You can wait for it and after its done, access the return code via the returncode attribute.
proc.wait()
The reason for this is the returncode is not automatically set when a process ends. You have to call .wait
print(proc.returncode)
Proc.wait() is needed in order to carry on the execution of the script

Short memo on Popen method

It allows you to have the returncode If the program doesn't wait the Popen function, returncode returns 'none'

IO Streams

The simplest way to get the output of a command, as seen previously, is to use the check_output function.
output = subprocess.check_output('ls')
print(output)
TO be continued..
  • Stderr and Stdout
  • Passing an evironment var

Trick commands

Excecute in a different working dir
subprocess.call('ls', cwd='/opt')
Killing and dieling process
proc = subprocess.Popen('sleep 10',shell=True)
proc.terminate()
proc.wait()     # There is nothing to wait, the 'terminate' has killed the running sleep command
print('exit')
Testing subprocess and Popen
proc = subprocess.Popen(['ls','-s','-l'])
print(proc)
proc.wait()   # Without
print('testing')