Python subprocess examples

Description

This is a collection of python subprocess examples for easy usage. Although I found the python documents are very comprehensive, I found there is not much examples of showing how to use. This document act as a note of how to use python subprocess package.

Environment settings

OSWindows 10 home
pythonAnaconda, python 3.6.3

Main functions

  • subprocess.run()

    the code is executed in IDLE command line window.

    >>> import subprocess as sb
    >>> bash_exec = "C:\\Program Files\\Git\\bin\\bash.exe"
    >>> sb.run([bash_exe, '-c','pwd'], stdout=sb.PIPE)
    

    CompletedProcess(args=[‘C:\Program Files\Git\bin\bash.exe’, ‘-c’, ‘pwd’], returncode=0, stdout=b’/c/Users/xxx/Anaconda3/Scripts\n’)

    NOTE:

    • need to point to bash exe
    • bash needs a "-c" condition in order to run it, otherwise a returncode=126 will return. Cannot using -i tag for bash command execution.
    • return result will not be shown if stdout is not set.
  • subprocess.Popen(*)

    However, I personally feel that the Popen is the most important tool of this subprocess package.

    Basic syntex

    >>> p = sb.Popen([bash_exe, '-c', 'pwd'], stdout=sb.PIPE, stderr=sb.PIPE)
    >>> p.communicate()
    

    (b’/c/Users/xxx/Anaconda3/Scripts\n’, b’’)

    this is working.

    The other one I thought it would work but actually not

    >>> p = sb.Popen(['-c','pwd'],executable=bash_exe, stdout=sb.PIPE, stderr=sb.PIPE)
    >>> p.communicate()
    

    (b’’, b’/usr/bin/pwd: /usr/bin/pwd: cannot execute binary file\n’)

    The error turn out to be a bit wired. For now, I am not sure how is this happened.

    env might be one very useful attributes when some info needs to be preloaded before executing the command.

    >>> p = sb.Popen([bash_exe, '-c', 'echo $NAME'], stdout=sb.PIPE, stderr=sb.PIPE)
    >>> p.communicate()
    

    (b’\n’, b’')

    >>> p = sb.Popen([bash_exe, '-c', 'echo $NAME'], stdout=sb.PIPE, stderr=sb.PIPE, env = {'NAME':'superman'})
    >>> p.communicate()
    

    (b’superman\n’, b’')

    context manager

    with sb.Popen([bash_exe, '-c', 'echo $NAME'], stdout=sb.PIPE, stderr=sb.PIPE, env = {'NAME':'superman'}) as proc:
    	proc.communicate()
    

    (b’superman\n’, b’')

    Not working:

    >>>with sb.Popen([bash_exe, '-c',], stdout=sb.PIPE, stderr=sb.PIPE, stdin = sb.PIPE, env = {'NAME':'superman'}) as proc:
    	proc.communicate(input=input())
    
    
    pwd
    

    (b’’, b’/usr/bin/bash: -c: option requires an argument\n')

    Eh, looks I can write a basic bash CLI?

    import subprocess as sb
    
    command = ''
    kernal = "C:\\Program Files\\Git\\bin\\bash.exe"
    
    while command!="exit":
        command = input('%: ')
        proc = sb.Popen([kernal,'-c',command], stdout=sb.PIPE, stderr=sb.PIPE, encoding = 'utf-8')
        out,err = proc.communicate()
        if err =='':
            print(out)
        else:
            print(err)
    

    However, if you input “cd” command, it actually doesn’t change its directory. SO, this CLI sucks.

    One easy solution is to use some libraries such as Pespect on Windows.

    NOTE:

    (TODO)

    this seems a good solution for building an interactive shell.