Saltar al contenido

Pasando variables a Subprocess.Popen

Solución:

Soltar shell=True. Los argumentos para Popen() se tratan de manera diferente en Unix si shell=True:

import sys
from subprocess import Popen, PIPE

# populate list of arguments
args = ["mytool.py"]
for opt, optname in zip("-a -x -p".split(), "address port pass".split()):
    args.extend([opt, str(servers[server][optname])])
args.extend("some additional command".split())

# run script
p = Popen([sys.executable or 'python'] + args, stdout=PIPE)
# use p.stdout here...
p.stdout.close()
p.wait()

Tenga en cuenta que pasando shell=True para comandos con entrada externa es un peligro para la seguridad, como se describe en una advertencia en los documentos.

Cuando usted llama subprocess.Popen puede pasar una cadena o una lista para que se ejecute el comando. Si pasa una lista, los elementos deben dividirse de una manera particular.

En su caso, debe dividirlo de la siguiente manera:

command = ["python",  "mytool.py", "-a", servers[server]['address'], 
           "-x", servers[server]['port'], 
           "-p", servers[server]['pass'], 
           "some",  "additional", "command"]
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

Esto se debe a que si pasa en una lista, Popen asume que ya ha dividido la línea de comando en palabras (los valores que terminarían en sys.argv), por lo que no es necesario.

De la forma en que lo está llamando, intentará ejecutar un binario llamado “python mytool.py -a”, que no es lo que quería decir.

La otra forma de solucionarlo es unir todas las palabras en una cadena (que Popen luego se separará – ver subprocess.list2cmdline). Pero es mejor que use la versión de lista si es posible: brinda un control más simple de cómo se divide la línea de comandos (si los argumentos tienen espacios o comillas, por ejemplo) sin tener que perder el tiempo con comillas.

Tu problema de tipo str por Primero Popen argumento. Reemplácelo por list. El siguiente código puede funcionar:

address = servers[server]['address']
port = servers[server]['port']
pass = servers[server]['pass']

command = "python mytool.py -a %s -x %d -p %s some additional command" % (address, port, pass)
p = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
#        it is a list^^^^^^^^^^^^^^^  shell=False

Si command los argumentos se obtienen de una fuente confiable que puede construir command y úsalo con shell=True de tal manera:

import pipes as p
command = "python mytool.py -a {} -x {} -p {} some additional command".format(p.quote(address), p.quote(port), p.quote(pass))
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

Nota 1: construido command con shell=Truees potencialmente inseguro. Usar pipes.quote() para reducir la posibilidad de inyección.
Nota 2: pipes.quote() obsoleto desde python2; por python3 usar shlex módulo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *