Os.system for calling exe, which is located in a directory whose name contains spaces

just my code is as follows:

file = 'C:\\Exe\\First Version\\filename.exe' os.system(file) 

when I run this program, windowserror is called, cannot find the specified file. I found out that the problem is related to the gap between the "First Version". Can I find a way around the problem?

PS: what if the file variable is passed as arg to another function?

+11
source share
5 answers

Putting quotes along the way will work:

 file = 'C:\\Exe\\First Version\\filename.exe' os.system('"' + file + '"') 

but the best solution is to use the subprocess module:

 import subprocess file = 'C:\\Exe\\First Version\\filename.exe' subprocess.call([file]) 
+13
source

Try enclosing it in double quotes.

 file = '"C:\\Exe\\First Version\\filename.exe"' os.system(file) 
+2
source

You can use a short file name with spaces in its name.

 file = 'C:\\Exe\\FirstV~1\\filename.exe' os.system(file) 
0
source

I used this:

 import subprocess, shlex mycmd='"C:\\Program Files\\7-Zip\\7z" x "D:\\my archive.7z" -o"D:\\extract folder" -aou' subprocess.run(shlex.split(mycmd)) 
0
source

It is true that the os.system will run the binary with spaces in the path, enclosing the path in quotation marks. (This should be a fairly obvious solution if you are used to using the terminal.) However, this alone does not solve the more painful problem with this function ... Once you do this, you may run into problems by adding arguments to your command ! (Ahh!)

All current recommendations now use the subprocess module instead of this old, frowning function. You can also use shlx to convert flat strings to lists for these subprocess functions. I also encountered problems or difficulties with these methods, which I won’t talk about ... Also, sometimes it is just easier to use os.system when all you need is a thin shell over a shell that implicitly displays output streams. on the console, works synchronously, etc. I would really like to have a built-in function to execute such a command on the shell, with absolutely zero parsing, wrapping, abstraction ...

Since there is no built-in without "filters", here is my solution patch for os.system . This is taken from my open source library. This has been tested on Windows, Mac, and Ubuntu Linux. I know that it’s not 100% reliable, and it’s more connected with a tan that you could hope for, but it’s not so bad.

When you call this _system() (passing the string to execute), simply _system() your long path in quotation marks and include any arguments you need with and without quotation marks. On the first “token” in the command, this will remove quotes and spaces in the path on Mac or Linux. On Windows, it uses the "short name", effectively deciding what it is in the given environment. This part of the code is a bit more complicated. It mainly uses a batch mechanism to resolve names and sends the results back through stderr in order to analyze what you would otherwise get for Popen() results on stdout. Here you can also use the working directory option and set it as an alternative solution.

I think I included all imports and determined what you need. If I missed something (copying and pasting the source spins), let me know.

 from os import system, getcwd, chdir from subprocess import Popen, PIPE import platform __plat = platform.system() IS_WINDOWS = __plat == "Windows" IS_LINUX = __plat == "Linux" IS_MACOS = __plat == "Darwin" __SCRUB_CMD_TMPL = "{0}{1}" __DBL_QUOTE = '"' __SPACE = ' ' __ESC_SPACE = '\\ ' if IS_WINDOWS : __BATCH_RUN_AND_RETURN_CMD = ["cmd","/K"] # simply assuming cmd is on the system path... __BATCH_ONE_LINER_TMPLT = "{0} 1>&2\n" # the newline triggers execution when piped in via stdin __BATCH_ESCAPE_PATH_TMPLT = 'for %A in ("{0}") do @echo %~sA' from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW __BATCH_ONE_LINER_STARTUPINFO = STARTUPINFO() __BATCH_ONE_LINER_STARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW def _system( cmd, wrkDir=None ): if wrkDir is not None: initWrkDir = getcwd() print( 'cd "%s"' % (wrkDir,) ) chdir( wrkDir ) cmd = __scrubSystemCmd( cmd ) print( cmd ) system( cmd ) print('') if wrkDir is not None: chdir( initWrkDir ) def __scrubSystemCmd( cmd ): """ os.system is more convenient than the newer subprocess functions when the intention is to act as very thin wrapper over the shell. There is just one MAJOR problem with it: If the first character in the command is a quote (to escape a long path to the binary you are executing), then the limited (undesirable) parsing built into the function can all fall apart. So, this scrub function solves that... """ if not cmd.startswith( __DBL_QUOTE ): return cmd cmdParts = cmd[1:].split( __DBL_QUOTE ) safeBinPath = _escapePath( cmdParts[0] ) args = __DBL_QUOTE.join( cmdParts[1:] ) # (the leading space will remain) return __SCRUB_CMD_TMPL.format( safeBinPath, args ) def _escapePath( path ): if not IS_WINDOWS: return path.replace(__SPACE, __ESC_SPACE) return( path if __SPACE not in path else __batchOneLinerOutput( __BATCH_ESCAPE_PATH_TMPLT.format(path) ) ) def __batchOneLinerOutput( batch ): cmd = __BATCH_ONE_LINER_TMPLT.format( batch ) p = Popen( __BATCH_RUN_AND_RETURN_CMD, shell=False, startupinfo=__BATCH_ONE_LINER_STARTUPINFO, stdin=PIPE, stdout=PIPE, stderr=PIPE ) # pipe cmd to stdin, return stderr, minus a trailing newline return p.communicate( cmd )[1].rstrip() 
0
source

All Articles