Reputation: 8107
Following script works fine when I try passing a batch file (that doesn't require any arguments) to the function.
script_as_var = os.path.join(os.environ['SOME_VAR'], 'bin/stop.bat')
jboss = os.path.join(os.environ['JBOSS_HOME'], 'bin/jboss-cli.bat')
def status(some_arg, cmd, more_arg):
print('CMD: ' + cmd)
ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = ps.communicate()[0]
...
...
status(10, script_as_var, 'last_arg') # Works fine
However, when I try passing below command to the function, it fails.
status(15, '[jboss,'"'-c'"','"'--commands="'"read-attribute server-state"'"'"']',
'some_arg')
Output:
CMD: [jboss,'-c','--commands='"read-attribute server-state"'']
...
FileNotFoundError: [WinError 2] The system cannot find the file specified
Below command used to work fine when I didn't create a function.
ps = subprocess.Popen([jboss,'-c','--commands='"read-attribute server-state"''],
stdout=subprocess.PIPE)
As you can notice from the output of print
command, I was successfully able to somehow (by using the messy single and double quotes combination) pass the exact command that I was able to run when this function was not created but it seems it sill needs some work for jboss
variable to expand.
Any idea how I can fix this?
Upvotes: 0
Views: 928
Reputation: 123413
The subprocess.Popen
constructor will accept either a string or a sequence like a list
as its first argument named args
. You code appears to be trying to use both...and here's how to do that correctly. As you can see, it's also expanding the jboss
variable as desired.
import os
os.environ['SOME_VAR'] = 'some_var' # For testing
os.environ['JBOSS_HOME'] = 'jboss_home_var' # For testing
script_as_var = os.path.join(os.environ['SOME_VAR'], 'bin/stop.bat')
jboss = os.path.join(os.environ['JBOSS_HOME'], 'bin/jboss-cli.bat')
def status(some_arg, cmd, more_arg):
print('CMD: ' + repr(cmd))
# ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
# output = ps.communicate()[0]
# ...
# ...
status(10, script_as_var, 'last_arg')
status(15, [jboss, '-c', '--commands="read-attribute server-state"'], 'some_arg')
Output:
CMD: 'some_var\\bin/stop.bat'
CMD: ['jboss_home_var\\bin/jboss-cli.bat', '-c', '--commands="read-attribute server-state"']
Upvotes: 2
Reputation: 1296
You're passing a str
for command. Note that your working example has a list
. You just need to get rid of all the extra quoting and pass a list.
>>> def foo(a, b, c):
print(b)
>>> jboss = 42
>>> foo(15,'[jboss,'"'-c'"','"'--commands="'"read-attribute server-state"'"'"']','some_arg')
[jboss,'-c','--commands="read-attribute server-state"']
>>> foo(15,[jboss,'-c','--commands="read-attribute server-state"'],'some_arg')
[42, '-c', '--commands="read-attribute server-state"']
Upvotes: 1