How do I add this: -param:abc=def
as a SINGLE command line argument?
Module subprocess
splits this up in TWO arguments by replacing the equal sign with a space.
Here is my python script:
import subprocess
pa=['test.bat', '--param:abc=def']
subprocess.run(pa)
Here is the test program:
@echo off
echo Test.bat
echo Arg0: %0
echo Arg1: %1
echo Arg2: %2
pause
and here the output:
Test.bat
Arg0: test.bat
Arg1: --param:abc
Arg2: def
Press any key to continue . . .
Because the equal sign is gone, the real app will not be started correctly. By the way, this problem also seems to happen when running on linux, with a sh script instead of a bat file.
I understand that removing the equal sign is a 'feature' in certain cases, e.g. with the argparse
module, but in my case I need to keep the equal sign. Any help is appreciated!
CodePudding user response:
Welcome to .bat file hell
To preserve equal sign, you'll have to quote your argument (explained here Preserving "=" (equal) characters in batch file parameters) ('"--param:abc=def"')
, but then subprocess
will escape the quotes
Test.bat
Arg0: test.bat
Arg1: \"--param:abc=def\"
Arg2:
Good old os.system
won't do that
import os
os.system('test.bat "--param:abc=def"')
result
Test.bat
Arg0: test.bat
Arg1: "--param:abc=def"
Arg2:
Damn, those quotes won't go off. Let's tweak the .bat script a little to remove them manually
@echo off
echo Test.bat
echo Arg0: %0
rem those 2 lines remove the quotes
set ARG1=%1
set ARG1=%ARG1:"=%
echo Arg1: %ARG1%
echo Arg2: %2
now it yields the proper result
Test.bat
Arg0: test.bat
Arg1: --param:abc=def
Arg2:
Alternatively, stick to subprocess
and remove quotes AND backslashes.
CodePudding user response:
I just checked, and you can use the shlex
package to parse the string before sending it to the shell:
import subprocess, shlex
pa = shlex.split('test.bat --param:abc=def') # parse string into a list
subprocess.run(pa)
Some info on the shlex
module:
It allows us to split strings using shell-like syntax, which is useful when working with the shell/command line. (docs)
Hope this helps.
CodePudding user response:
As Jean-Francois said, this is caused by BAT file Hell:
C:\>test.bat -param:abc=def
Test.bat
Arg0: test.bat
Arg1: -param:abc
Arg2: def
Press any key to continue . . .
Powershell does a better job, test.ps1:
write-host "There are a total of $($args.count) arguments"
for ( $i = 0; $i -lt $args.count; $i ) {
write-host "Argument $i is $($args[$i])"
}
Running from the DOS prompt:
PS C:\> .\test.ps1 --params:abc=def
There are a total of 1 arguments
Argument 0 is --params:abc=def
Conclusion:
There is nothing wrong with Python.
Because the app that I need to start from Python has a BAT startup script, I have to replace that by a Powershell version *.ps1 script.