3

I am using subprocess.check_output() method to execute commands from within the python script. There are some commands that need " (double quotes) to be present in syntax.

Here's one example:

> drozer console connect -c "run app.package.info -a com.package.name"

It throws error if we remove " (double quotes) from above command.

I did the following :

string = '\"run app.package.info -a com.package.name\"'
command = ['/usr/bin/drozer','console','connect','-c',string]
output = subprocess.check_output(command)

This yields me to error:

*** Unknown syntax: "run app.package.info  -a com.package.name"

How can I solve this issue of quotes?

GG.
  • 21,083
  • 14
  • 84
  • 130
node_analyser
  • 1,502
  • 3
  • 17
  • 34

3 Answers3

9

You don’t need the double quotes.

The reason you need them with the shell command is that the shell is parsing the command line from a string, and it uses them as an indication that the text run app.package.info -a com.package.name should be placed in a single argument:

#!/usr/bin/env python
import subprocess

c_arg = 'run app.package.info -a com.package.name'
command = ['/usr/bin/drozer', 'console', 'connect', '-c', c_arg]
output = subprocess.check_output(command)
print("Got %r" % (output,))

When you’re using code to start a process, you explicitly specify individual arguments, and no shell parsing is going on, so there’s no need for the extra quotes.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
al45tair
  • 4,405
  • 23
  • 30
  • I tried passing "run app.package.info -a com.package.name" without quotes but it gives error. – node_analyser Mar 06 '14 at 12:53
  • 1
    @v1h5 You need to change the line `string = '\"\"'` by removing the `\"`s. That should work. – al45tair Mar 06 '14 at 13:13
  • 2
    @v1h5, "gives error" isn't clear enough for us to be very much help -- specify the exact thing you ran, and the exact error. This answer really is the best-practices approach, and identical to what the shell would do in the command line you gave. – Charles Duffy Mar 06 '14 at 13:15
  • @alastair : hi, I used "pexpect" module instead of "popen" and now everything is working fine. – node_analyser Mar 07 '14 at 10:07
  • I was thinking that problem was that double quotes were not sent correctly but didn't think of not sending them solves the issue. thanks! – Hayashi Yoshiaki Nov 13 '22 at 12:59
2

To solve your problem you need a split method that understands subprocess command argument requirements. Use shlex like:

>>> import shlex
>>> import subprocess
>>> 
>>> command = 'drozer console connect -c "run app.package.info -a com.package.name"'
>>> command = shlex.split(command)
>>> command
['drozer', 'console', 'connect', '-c', 'run app.package.info -a com.package.name']
>>> output = subprocess.check_output(command)
Mohammad Azim
  • 2,604
  • 20
  • 21
-1

You could try to use the option shell=True like:

output = subprocess.check_output(command, shell=True)
theaembee
  • 69
  • 3
  • 2
    It’s best not to use the shell if you don’t have to. Not only does it save creating an extra process, but it avoids any security risks associated with argument parsing. – al45tair Mar 06 '14 at 13:12
  • Though the error is gone but now there is no output. – node_analyser Mar 06 '14 at 14:44
  • You need additional refactoring for this to work, and eventually adding a shell is something you want to avoid when it's not necessary. See also [Actual meaning of `shell=True` in subprocess](https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess) – tripleee Oct 31 '22 at 08:37