Handling a literal space in a filename - python

I have problem with os.access(filename, os.R_OK) when file is an absolute path on a Linux system with space in the filename. I have tried many ways of quoting the space, from "'" + filename + "'" to filename.replace(' ', '\\ ') but it doesn't work.
How can I escape the filename so my shell knows how to access it? In terminal I would address it as '/home/abc/LC\ 1.a'

You don't need to (and shouldn't) escape the space in the file name. When you are working with a command line shell, you need to escape the space because that's how the shell tokenizes the command and its arguments. Python, however, is expecting a file name, so if the file name has a space, you just include the space.

Related

Change my current working directory to another directory including spaces

I have a Python method that first changes the working directory to a specific path and then needs to execute a command - below is an extract of same:
def start_testing_binary(self, command, path, binary, args, config):
os.chdir(path)
cmd = command.replace('"', '') + binary+ args.replace('"', '') + config.replace('"', '')
return cmd
When I invoke the method with a system path having spaces in between I get below error:
start_testing_binary("myexe", "C:\\Users\\Project Work\\bin", ".exe", "-c" , "myinfo.ini")
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: '"C:\\Users\\Project Work\\bin"'
But when I hardcode its value in below call as mentioned:
os.chdir("C:\\Users\\Project Work\\bin")
The code does not reports any error - how can I fix this issue of having path being passed as argument?
os.chdir seems to be very nice to accept the space.
Add \\ in front of it to escape it when used as an argument!?
Or put the path in quotes with \", or easier put the path as '"path next_part"' (single then double quotes) ?
See also How do I execute a program from Python? os.system fails due to spaces in path

Permission error when running jar from python

I have a .jar archive that loads a file and then does some things with it and writes it to the disk again.
If I call this .jar directly from the command prompt, everything works. But when I try to do it from within python, I get the following error:
Input file ("C:\xxx.txt") was not found or was not readable.
This is my python code:
import sys, os, subprocess
if os.path.isdir(sys.argv[1]):
for file in os.listdir("."):
print (" ".join(['java', '-jar', sys.argv[2], 'd', "\"" + os.path.abspath(file) + "\"", "\""+os.path.join(os.path.join(os.path.abspath(os.path.dirname(file)), "output"), file) + "\""]))
subprocess.call(['java', '-jar', sys.argv[2], 'd', "\"" + os.path.abspath(file) + "\"", "\""+os.path.join(os.path.join(os.path.abspath(os.path.dirname(file)), "output"), file) + "\""])
When I copy the printed statement into the commandline, the jar executes perfectly; everything works. I tried running cmd as an admin, but that didn't help.
The problem is the extra quotes you're adding. When you pass subprocess a list of args, it already quotes them appropriately; if you quote them yourself, it'll end up quoting your quotes, so instead of passing an argument that, when unquoted, means C:\xxx.txt, you'll be passing an argument that, when unquoted, means "C:\xxx.txt", which is not a valid pathname.
The rule of thumb for Windows* is: If you know exactly what each argument should be, pass them as a list, and don't try to quote them yourself; if you know exactly what the final command-line string should be, pass it as a string, and don't try to break it into a list of separate arguments yourself.
* Note that this is only for Windows. On POSIX, unless you're using shell=True, you should basically never use a string.

Python Writing to a new file - But wrong EOL Conversion

My script writes to and creates a new file but it is currently making it in Mac EOL Conversion instead of Windows. This means that each line ends with only 'CR' instead of 'CR LF' which won't work for what i'm trying to do.
Now why this is, or how I can change it?
f = open('...')
text_file1.write(str(i) + ',' + harvestServer + ',' + finalString + harvestCommand + '\r')
text_file1.close()
Replace the \r with \n, having made sure you open the file in text mode. This will use the native convention for your platform (that is, os.linesep).
Alternatively, open the file in binary mode and use \r\n. This will use the Windows convention no matter where you run your code.
Finally, you can control the newline translation by giving the optional newline argument to open().

Passing shell commands with Python os.system() or subprocess.check_call()

I'm trying to call 'sed' from Python and having troubles passing the command line via either subprocess.check_call() or os.system().
I'm on Windows 7, but using the 'sed' from Cygwin (it's in the path).
If I do this from the Cygwin shell, it works fine:
$ sed 's/&nbsp;/\ /g' <"C:foobar" >"C:foobar.temp"
In Python, I've got the full pathname I'm working with in "name". I tried:
command = r"sed 's/&nbsp;/\ /g' " + "<" '\"' + name + '\" >' '\"' + name + '.temp' + '\"'
subprocess.check_call(command, shell=True)
All the concatenation is there to make sure I have double quotes around the input and output filenames (in case there are blank spaces in the Windows file path).
I also tried it replacing the last line with:
os.system(command)
Either way, I get this error:
sed: -e expression #1, char 2: unterminated `s' command
'amp' is not recognized as an internal or external command,
operable program or batch file.
'nbsp' is not recognized as an internal or external command,
operable program or batch file.
Yet, as I said, it works OK from the console. What am I doing wrong?
The shell used by subprocess is probably not the shell you want. You can specify the shell with executable='path/to/executable'. Different shells have different quoting rules.
Even better might be to skip subprocess altogether, and write this as pure Python:
with open("c:foobar") as f_in:
with open("c:foobar.temp", "w") as f_out:
for line in f_in:
f_out.write(line.replace('&nbsp;', ' '))
I agree with Ned Batchelder's assessment, but think what you might want to consider using the following code because it likely does what you ultimately want to accomplish which can be done easily with the help of Python's fileinput module:
import fileinput
f = fileinput.input('C:foobar', inplace=1)
for line in f:
line = line.replace('&nbsp;', ' ')
print line,
f.close()
print 'done'
This will effectively update the given file in place as use of the keyword suggests. There's also an optional backup= keyword -- not used above -- which will save a copy of the original file if desired.
BTW, a word of caution about using something like C:foobar to specify the file name because on Windows it means a file of that name in whatever the current directory is on drive C:, which might not be what you want.
I think you'll find that, in Windows Python, it's not actually using the CygWin shell to run your command, it's instead using cmd.exe.
And, cmd doesn't play well with single quotes the way bash does.
You only have to do the following to confirm that:
c:\pax> echo hello >hello.txt
c:\pax> type "hello.txt"
hello
c:\pax> type 'hello.txt'
The system cannot find the file specified.
I think the best idea would be to use Python itself to process the file. The Python language is a cross-platform one which is meant to remove all those platform-specific inconsistencies, such as the one you've just found.

Windows error and python

I'm working on a bit of code that is supposed to run an exe file inside a folder on my system and getting an error saying...
WindowsError: [Error 3] The system cannot find the path specified.
Here's a bit of the code:
exepath = os.path.join(EXE file localtion)
exepath = '"' + os.path.normpath(exepath) + '"'
cmd = [exepath, '-el', str(el), '-n', str(z)]
print 'The python program is running this command:'
print cmd
process = Popen(cmd, stderr=STDOUT, stdout=PIPE)
outputstring = process.communicate()[0]
I have imported subprocess and also from subprocess import *
For example, This is how my exe file location looks like in the first line of the code I show:
exepath= os.path.join('/Program Files','next folder','next folder','blah.exe')
Am I missing something?
You need to properly escape the space in the executable path
Besides properly escaping spaces and other characters that could cause problems (such as /), you can also use the 8 character old DOS paths.
For example, Program Files would be:
Progra~1 , making sure to append ~1 for the last two characters.
EDIT: You could add an r to the front of the string, making it a raw literal. Python would read the string character for character. Like this:
r " \Program files"
If I remember correctly, you don't need to quote your executuable file path, like you do in the second line.
EDIT: Well, just grabbed nearby Windows box and tested this. Popen works the same regardless the path is quoted or not. So this is not an issue.
AFAIK, there is no need to surround the path in quotation marks unless cmd.exe is involved in running the program.
In addition, you might want to use the environment variable ProgramFiles to find out the actual location of 'Program Files' because that depends on regional settings and can also be tweaked using TweakUI.

Categories