python and windows double backslash - python

I got a program running on my local machine which uses some files. I create the reference to the files by using: os.path.join( tempfile.gettempdir(), 'filename.txt' )
After that I'm running a program which accepts some parameters --log-file filepath where filepath is one of the files I just explained above.
On my machine python creates backslashes for the paths but not double backslashes and the program complains because it's considered an escape character and should be a double backslash.
Is there any standard way of making sure that I get a working path with double backslashes in python? I could use regex but I would prefer something similar to what os. provides. Maybe I'm missing something.
I'm calling the program using subprocess.Popen:
self._proc = subprocess.Popen( command.split( ' ' ) )
where command is something like pcix.exe --log-file file_path
Also, running a test on my console shows that my python does not produce double backslash for paths:
>>> print os.path.join(tempfile.gettempdir(), "test.txt")
c:\users\manilo~1\appdata\local\temp\test.txt
Leaving out the print command produces the same path:
>>> os.path.join(tempfile.gettempdir(), "test.txt")
c:\users\manilo~1\appdata\local\temp\test.txt
Any idea why?
P.S. The platform i'm running is CPython

Try:
print os.path.join(tempfile.gettempdir(), "test.txt").replace('\\\\','\\\\\\\\')

Related

Run a powershell script from python where the path contains spaces

I've found that python can run other programs using the subprocess module. I want to use python to run a powershell script that is in a directory location that contains spaces. How do I handle the spaces in the python script below?
import subprocess
powershellExeLocation = r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
powershellScriptLocation = r"C:\Users\username\Documents\testPowershell.ps1"
print('running script with no spaces')
#this works
subprocess.run([powershellExeLocation, powershellScriptLocation])
#this doesn't work
print('running script with spaces')
powershellScriptLocationWithSpaces = r"C:\Users\username\path with spaces\testPowershell.ps1"
subprocess.run([powershellExeLocation, powershellScriptLocationWithSpaces])
Try this:
subprocess.run([powershellExeLocation, "-File", powershellScriptLocationWithSpaces])
The script location needs a set of literal quotes around it, so powershell.exe knows to treat it as one single filename.
subprocess.run([powershellExeLocation, '"' + powershellScriptLocationWithSpaces + '"'])

Open a command prompt at a specific location followed by running a script at that location with some command line arguments using python

I was able to open command prompt and change the directory to required location using the subprocess module, but I was unable to pass further arguments to run an application along with some command line arguments. I am new to the subprocess module, so I did some search over stackoverflow couldn't find the desired result.
Mycode:
import subprocess
path = r"C:/Users/Application_Folder"
p = subprocess.Popen(r"cmd.exe", cwd="C:/Project_Files", shell=True)
Desired output:
Path: C:\Users\Application_folder\Application.exe
Need to open the cmd prompt in windows at the Application_folder location,
run the Application.exe by passing some command line arguments, using python
Just pass the command line you actually want to execute, with the executable path and whatever arguments you want to pass:
command_line = [r'C:\Users\Application_Folder\Application.exe', '/argument1', '/argument2']
p = subprocess.Popen(command_line, cwd=r'C:\Project_Files')
A couple of notes to keep in mind:
You shouldn't use shell=True. It's not necessary here -- in fact it's almost never necessary -- but it does introduce a potential security risk.
The whole point of raw string literals (starting with r' or r") is to change how backslash characters within the string are interpreted. r'C:\Program Files' is exactly the same string as "C:\\Program Files". If your string doesn't have backslashes in it, don't bother using the r prefix.

Adding paths to arguments in popen

I want to execute a Linux command through Python. This works in the terminal:
/usr/bin/myprogram --path "/home/myuser"
I've tried this:
path = "/home/myuser"
args = ['/usr/bin/myprogram', '--path ' + path]
proc = subprocess.Popen(args)
And this:
path = "/home/myuser"
args = ['/usr/bin/myprogram', '--path "' + path + '"']
proc = subprocess.Popen(args)
But myprogram does not accept the path formatting. I know that paths behave differently when not executing as shell but I can't get it working. I've also tried single quoting the path instead of double quoting it. Bonus points for a solution that also works on Windows (with a different program path, obviously).
EDIT: Sorry, was writing this out from memory and used backslashes instead of forward slashes. The actual code did use the (correct) forward slashes.
Here's something to try:
import subprocess
import shlex
p = subprocess.Popen(shlex.split("/usr/bin/myprogram --path /home/myuser")
Mind the forward slashes ("/"). From what I read, Python doesn't like backslashes ("\") even when running on Windows (I've never used it on Windows myself).
The problem comes from your string literal, '\usr\bin\myprogram'. According to escaping rules, \b is replaced by \x08, so your executable is not found.
Pun an r in front of your string literals (i.e. r'\usr\bin\myprogram'), or use \\ to represent a backslash (i.e. '\\usr\\bin\\myprogram').

Xcopy with Python

I'm trying to get xcopy working with python to copy files to a remote system. I am using a very simple test example:
import os
src = "C:\<Username>\Desktop\test2.txt"
dst = "C:\Users\<Username>"
print os.system("xcopy %s %s" % (src, dst))
But for some reason when I run this I get:
Invalid number of parameters
4
Running the xcopy directly from the command line works fine. Any ideas?
Thanks
\t is a tab character. I'd suggest using raw strings for windows paths:
src = r"C:\<Username>\Desktop\test2.txt"
dst = r"C:\Users\<Username>"
This will stop python from surprising you by interpreting some of your backslashes as escape sequences.
In addition to using raw string literals, use the subprocess module instead of os.system - it will take care of quoting your arguments properly if they contain spaces. Thus:
import subprocess
src = r'C:\<Username>\Desktop\test2.txt'
dst = r'C:\Users\<Username>'
subprocess.call(['xcopy', src, dst])
Try prefixing your strings with r. So r"C:\<Username>\Desktop\test2.txt". The problem is that a backslash is treated as a special character within strings.

How to copy file to path that contains ampersand '&' using Python's shutil?

I am complete newbie in Python and have to modify existing Python script. The script copies file to other path like following:
err=shutil.copyfile(src, dst)
This works unless dst contains character like &:
dst = "Y:\R&D\myfile.txt"
In this case I get windows error popup that says
Open file or Read file error
Y:\R
I tried to escape & using back slash, double back slash and wrapping the string with additional quotes: dst = "\"Y:\R&D\myfile.txt\"".
Nothing works in last case I get "invalid path" error message from shutil.
How can I solve this problem?
I doubt that ampersand is supported on most platforms. You will likely have to make a call to a windows specific program. I suggest robocopy since its really good at copying files. If it's not included in your version of windows, you can find it in the windows server administrator toolkit for 2003.
It works for me if I change all the \ in the filepaths to / (in both src and dst strings). Yes, I know you're using Windows, but filepaths always seem to be less fussy in Python if you use /, even in Windows.
Also, it looks like you're copying to a network drive. Do you get the same problem copying to c:\R&D\?
What flavor of Windows are you using? shutil.copyfile() works fine for me with & in directory names, in both src and dst paths, in both local and network drives on XP -- as long as I use / in place of \.
Easiest solution, signify to python that the string is raw and not to escape it or modify it in any way:
import shutil
src = r"c:\r&d\file.txt"
dst = r"c:\r&d\file2.txt"
err=shutil.copyfile(src, dst)
Try to escape the "\" with "\ \", this command must work (for example):
shutil.copyfile("Y:\\R&D\\myfile.txt", "C:\\TMP")
Here are few ways to make it work on windows:
Approach 1: (already explained)
import shutil; shutil.copy(src,dest)
as long as src/dest are using r'c:\r&d\file' string format. It also works with forward "/" slashes as well.
Approach 2: Notice use of double quotes instead of single quotes on windows.
src = r'c:\r & d\src_file'
os.system('copy "{}" "{}"'.format(src,dest))
1 file(s) copied
Last resort:
with open(dest, 'wb') as f:
f.write(open(src,'rb').read())
Unlike os.system, this preferred implementation subprocess.call could not work with any quoting approach on windows. I always get The specified path is invalid. Did not try on unix.

Categories

Resources