user248237
user248237

Reputation:

properly handling shell escaping from Python using os.system

I'm having trouble properly escaping calls to the shell from within Python, using the os.system command. I'm trying to do the equivalent of:

$ cat test | sort --stable -t $'\t' -k1,1

from within Python, passing that to the shell.

I tried:

import os
cmd = "cat %s | sort --stable -t $'\\t' -k1,1" %("test")
os.system(cmd)

but I get the error:

sort: multi-character tab `$\\t'

although it works correctly from the shell. I tried to escape the \t by adding an extra slash in Python, but I must be missing something else. Any idea how this can be fixed?

thanks.

Upvotes: 5

Views: 3757

Answers (2)

Mark Edgar
Mark Edgar

Reputation: 4827

First, you should avoid useless-use-of-cat: http://google.com/search?q=uuoc.

Secondly, are you sure that your sort command not understand backslash-t? This should work:

sort --stable -t'\t' -k1,1 test

It should also work just fine from Python:

os.system("sort --stable -t'\\t' -k1,1 test")
# or
os.system(r"sort --stable -t'\t' -k1,1 test")

Finally, if you switch to subprocess (recommended), avoid using shell=True:

subprocess.call(["sort", "--stable", "-t\t", "-k1,1", "test"])

Upvotes: 1

Nathan Stocks
Nathan Stocks

Reputation: 2164

os.system doesn't execute commands in a normal bash environment like you would expect. You can work around it by simply calling bash yourself:

import os
cmd = """/bin/bash -c "cat %s | sort --stable -t $'\t' -k1,1" """ % "test"
os.system(cmd)

But you should be aware that os.system has been marked as deprecated, and will be removed in future versions of python. You can future-proof your code by using subprocess's convenience method call that mimics os.system's behavior:

import subprocess
cmd = """/bin/bash -c "cat %s | sort --stable -t $'\t' -k1,1" """ % "test"
subprocess.call(cmd, shell=True)

There are more ways to make that call with the subprocess module if you are interested:

http://docs.python.org/library/subprocess.html#module-subprocess

Upvotes: 5

Related Questions