PDA

View Full Version : [SOLVED] Automatic backslash escape sequences?



Jadd
June 19th, 2008, 01:47 PM
When coding in python, I frequently write lines similar to these:

import subprocess
# filename is a previously assigned string variable
subprocess.call("mkdir -p %s" % filename, shell=True)

This works great, until the filename contains special characters, such as a space. A solution would be:

subprocess.call("mkdir -p %s" % filename.replace(" ", "\\ "), shell=True)
However, I'm sure that the space character is not the only one that needs to be replaced with a escape sequence. What other the other ones? Is there a function that automatically replaces the special character with their escape sequences?

dtmilano
June 19th, 2008, 02:39 PM
Use, for example

os.makedirs('this/is the path/to /my dir')

Jadd
June 19th, 2008, 03:06 PM
Thanks, but I was hoping for something that I could use in general, not just for mkdir. I'd like to do

subprocess.call("randomcommand %s" % transform(filename), shell=True)
where transform is the function I'm looking for.

Martin Witte
June 19th, 2008, 07:47 PM
A filename with a space is not invalid, you can create it by putting it in single quotes:

>>> import subprocess
>>> subprocess.call("mkdir -p '%s'" % 'Directory name with spaces', shell=True)
0

geirha
June 19th, 2008, 08:43 PM
import os,subprocess
subprocess.call(['mkdir', '-p', '/tmp/directory with sp/aces and\n stuff'])
os.spawnvp(os.P_WAIT, 'mkdir', ['mkdir', '-p', '/tmp/directory with sp/aces and\n stuff'])

ghostdog74
June 20th, 2008, 12:59 AM
for less worry about which way the slashes go, you can try to use os.path.join().

Can+~
June 20th, 2008, 01:40 AM
Use raw strings, not that it will solve your problem, but it usually helps with escape characters.

normal_string = "this is some string\nasddsadsds."
a_raw_string = r"this is some string\nasddsadsds."

Jadd
June 21st, 2008, 10:25 AM
import os,subprocess
subprocess.call(['mkdir', '-p', '/tmp/directory with sp/aces and\n stuff'])
os.spawnvp(os.P_WAIT, 'mkdir', ['mkdir', '-p', '/tmp/directory with sp/aces and\n stuff'])

Thanks, that's exactly what I need.

Jadd
June 21st, 2008, 01:35 PM
I just came accross an issue with this solution.
Running this command in a terminal will give an error:

gksu gedit --new-window new\ file.txt
The solution of course is:

gksu "gedit --new-window new\ file.txt"
So in python, I now have a problem:

import subprocess
filename = "new file.txt"
# this prints an error
subprocess.call(["gksu", "gedit", "--new-window", filename])
# this opens two files in gedit: new and file.txt
subprocess.call(["gksu", "gedit --new-window %s" % filename])
How do I deal with this?

geirha
June 21st, 2008, 01:42 PM
If you use gksudo instead of gksu, the first one of your subprocess.calls above should work.

EDIT:
Actually both (gksu and gksudo) should work, I just tested myself, and the problem is that gksu/gksudo is "taking" the options that should be passed to gedit. use -- to tell gksu to stop parsing options.


subprocess.call(["gksu", "--", "gedit", "--new-window", filename])

Jadd
June 21st, 2008, 01:49 PM
Brilliant! That -- trick is just what I need.

Jadd
July 2nd, 2008, 02:51 PM
I just discovered that bash uses single quotes to preserve the literal value of a string (including spaces and stuff). The only problem with that is when your filename includes single quotes, but I found the workaround (http://muffinresearch.co.uk/archives/2007/01/30/bash-single-quotes-inside-of-single-quoted-strings/).

So here's some code with their results:


import subprocess
# we need to pass shell as True to let bash interpret the single quotes as it normally would
subprocess.call("touch 'a new day.txt'", shell=True) # creates: a new day.txt
subprocess.call(r"touch 'a'\''new'\''day.txt'", shell=True) # creates: a'new'day.txt


Here's a function I wrote to automatically surrond with single quotes, replacing any single quotes with the appropriate string:

#!/usr/bin/env python
import subprocess

def surround_with_single_quotes(string):
"""Surrounds the passed string with single quotes and replaces any
quotes with '\'' required by bash
>>> surround_with_single_quotes("a'new'day.txt")
"'a'\\\\''new'\\\\''day.txt'"

The previous example returns (without python's quotes and escape sequences):
'a'\''new'\''day.txt'
"""
str = string.replace("'", r"'\''")
str = "'" + str + "'"
return str

if __name__ == "__main__":
import doctest
doctest.testmod()
subprocess.call("touch " + surround_with_single_quotes("a'new'day.txt"), shell=True)