subprocess.popen function with quotes

Kurt Smith kwmsmith at gmail.com
Wed Mar 26 01:53:29 EDT 2008


On Wed, Mar 26, 2008 at 12:15 AM, skunkwerk <skunkwerk at gmail.com> wrote:
> On Mar 25, 9:25 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
>  wrote:
>  > En Wed, 26 Mar 2008 00:39:05 -0300, skunkwerk <skunkw... at gmail.com>
>  > escribió:
>
> >
>  > >>    i'm trying to call subprocess.popen on the 'rename' function in
>  > >> linux.  When I run the command from the shell, like so:
>  >
>  > >> rename -vn 's/\.htm$/\.html/' *.htm
>  >
>  > >> it works fine... however when I try to do it in python like so:
>  > >> p = subprocess.Popen(["rename","-vn","'s/\.htm$/
>  > >> \.html/'","*.htm"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>  >
>  > >> print p.communicate()[0]
>  >
>  > >> nothing gets printed out (even for p.communicate()[1])
>  >
>
> > I'd try with:
>  >
>  > p = subprocess.Popen(["rename", "-vn", r"'s/\.htm$/\.html/'", "*.htm"],
>  >        stdout=subprocess.PIPE, stderr=subprocess.PIPE,
>  >        shell=True)
>  >
>  > (note that I added shell=True and I'm using a raw string to specify the
>  > reg.expr.)
>  >
>  > --
>  > Gabriel Genellina
>
>  Thanks Gabriel,
>    I tried the new command and one with the raw string and single
>  quotes, but it is still giving me the same results (no output).  any
>  other suggestions?

I had similar problems passing quoted arguments to grep -- I don't
have rename on my system so I can't do an exact translation.

First version, passing argument to grep that would normally have to be
quoted if typed in shell:

In [1]: from subprocess import *

In [2]: p1 = Popen(['ls'], stdout=PIPE)

In [3]: p2 = Popen(['grep', '[0-9]\{7\}'], stdin=p1.stdout,
stdout=PIPE) # note that the grep regex isn't double quoted...

In [4]: output = p2.communicate()[0]

In [5]: print output
cur0046700.png
cur0046700_1.png
cur0046750.png
dendat0046700.png
dendat0046700_1.png
dendat0046750.png

And we see that everything is hunky dory.

Now, trying to pass grep a quoted argument:

In [10]: p1 = Popen(['ls'], stdout=PIPE)

In [11]: p2 = Popen(['grep', '"[0-9]\{7\}"'], stdin=p1.stdout, stdout=PIPE)

In [12]: output = p2.communicate()[0]

In [13]: print output


In [14]:

And we get nothing.  N.B. that's a single-quote double-quote string
argument to grep in the second example, not a triple single quote.

Incidentally, a triple quoted string will work as well.

Moral from this example:  when passing arguments that would normally
be quoted to be safe from the shell's expansion, etc,  don't.  Just
pass it using Popen(['cmd', 'arg-that-would-normally-be-quoted']) and
it will be passed directly to the function without the shell's
intervention.

Since the argument is passed directly to the command (rename in your
case, grep in this one) quoting to preserve special characters isn't
needed, and the quotes will be passed as part of the argument, giving
the null results you got above.

Kurt



More information about the Python-list mailing list