Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad to use subprocess.call() or os.system() when writing Python shell scripts?

Tags:

I was researching on whether or not Python can replace Bash for shell scripting purposes. I have seen that Python can execute Linux commands using subprocess.call() or os.system(). But I've read somewhere (forgot the link of the article) that using these is a bad thing. Is this really true?

If yes, then why is it a bad thing?

If not, then is it safe to say that Python can indeed replace Bash for scripting since I could just execute Linux commands using either of the 2 function calls?

Note: If I'm not mistaken, os.system() is deprecated and subprocess.call() should be used instead but that is not the main point of the question.

like image 607
Patrick Avatar asked Jun 09 '17 13:06

Patrick


1 Answers

Using os.system() or subprocess.call(..., shell=True) can't replace a shell, because they actually use the shell.

os.system("foo") actually invokes sh -c "foo" -- that is to say, it runs foo as a shell script. Using this, then, is in no respect replacing a shell. This is also true in the exact same way for subprocess.call("foo", shell=True).


Using subprocess.Popen and functions from that family can replace a shell, but this often results in verbose and unwieldy code.

Consider the following shell script:

#!/bin/sh
foo "$1" | bar "$2"

Now, let's look at what it takes to reproduce that in Python in a way that doesn't start any shell under-the-hood:

#!/usr/bin/env python
import subprocess, sys

p1 = subprocess.Popen(["foo", sys.argv[1]], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["bar", sys.argv[2]], stdin=p1.stdout)
sys.exit(p2.wait())

We went from 19 characters (after the shebang) to 148 characters (after the shebang and imports) -- and this was for a completely trivial script, one not using fancier features such as process substitution, command substitution, or the like.

like image 92
Charles Duffy Avatar answered Oct 13 '22 17:10

Charles Duffy