简体   繁体   中英

Python, os.system and subprocess.call both don't work for variable string command

I'm trying to issue a command to another application using python, but it seems to only acknowledge part of the command. Here are the lines of code in question:

command = 'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)
print (command)
os.system(command)

I'm fairly new to Python so forgive me if that's a weird way to construct a string for a directory name containing many variables. However, the print function always returns the exact command that I intended, and it will run as intended if I simply copy and paste it into the command prompt manually.

potreeconverter C:\Users\thomas\source\test.las -q NICE -p test –o C:\Users\thomas\source\55555\55555\test

The command is accepted by the application, but it ignores the -o parameter, which specifies an output directory for the application. It does the same thing if I use subprocess.call. No other part of the command is ever ignored.

I read that this issue can be solved by having python write the command to a batch file, and then sending the batch file through. I would really rather not do that because it would be pretty inefficient. Is there another way that anyone knows of to avoid this?

Also, I'm unsure what this means but I thought it was odd and perhaps significant. When this problem occurs, and only when this problem occurs, the default output directory that the program chooses instead of the one I specified will use forward slashes instead of backslashes.

you need to escape your backslashes.
a backslash is a special character, and that is why you are able to encode special characters like tabs ( \\t ), newlines ( \\n ) and a bunch more.
so you could just replace this:

command = 'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)  

with:

command = 'potreeconverter {} -q NICE -p {} –o {}\\{}\\{}\\{}'.format(path,folder,pathup[0],cid,wpid,folder) 

you could also use python's raw string notation , which I, personally consider nicer, and easier to maintain:

command = r'potreeconverter {} -q NICE -p {} –o {}\{}\{}\{}'.format(path,folder,pathup[0],cid,wpid,folder)

what this does is it simply tells python not to count any character as special (except for format strings, but that kind of doesn't count).
now, as to what you said about it being a strange way to make paths, there is a better way, which is os.path.join . this takes any arguments, and joins them as a path. for example it would do:

>>> os.path.join('C:\\tuna', 'fish', 'directory')
'C:\\tuna\\fish\\directory'
>>>

there are 3 major advantages here: it will choose between / or \\ depending on the system ( \\ on windows\\DOS, / on Unix/Linux, etc...), it can take any amount of arguments, and is more readable. in your case, you could do:

import os.path

base = 'potreeconverter {} -q NICE -p {} –o'
path = os.path.join(pathup[0], cid, wpid, folder)
command = ' '.join((base, path))

your code would work too, but this is the recommended way for working with paths.
if you have any questions, please ask. have a good day!

Just to make sure I don't leave everyone hanging, I figured out the solution. It's very strange. All I did was call the parameters in a different order, and now it works every time. They work in any order if I input the command manually, but if I issue the command from python it seems it will only work if I write the output parameter first. Not sure if this is a problem with python or with the application I'm writing the command to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM