Creo que ejecutar un comando externo con un entorno ligeramente modificado es un caso muy común. Así es como tiendo a hacerlo:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
Tengo el presentimiento de que hay una mejor manera; se ve bien?
python
subprocess
popen
Oren_H
fuente
fuente
os.pathsep
lugar de ":" para rutas que funcionan en plataformas. Ver stackoverflow.com/questions/1499019/…/usr/sbin
:-)Respuestas:
Creo que
os.environ.copy()
es mejor si no tiene la intención de modificar el entorno os.iron para el proceso actual:fuente
os.environ.copy
de laenv
variable, pero es necesario asignar el resultado de una llamada al métodoos.environ.copy()
aenv
.shell=True
en susubprocess.Popen
invocación. Tenga en cuenta que existen posibles implicaciones de seguridad al hacerlo.my_command
es solo un comando para ejecutar. Podría ser, por ejemplo,/path/to/your/own/program
o cualquier otra declaración "ejecutable".Eso depende de cuál sea el problema. Si es para clonar y modificar el entorno, una solución podría ser:
Pero eso depende en cierta medida de que las variables reemplazadas sean identificadores válidos de Python, que lo son con mayor frecuencia (¿con qué frecuencia se encuentra con nombres de variables de entorno que no son alfanuméricos + guiones bajos o variables que comienzan con un número?).
De lo contrario, podría escribir algo como:
En el caso muy extraño (¿con qué frecuencia usa códigos de control o caracteres no ascii en los nombres de las variables de entorno?) Que las claves del entorno son
bytes
que no puede (en python3) incluso usar esa construcción.Como puede ver, las técnicas (especialmente la primera) que se usan aquí, los beneficios en las claves del entorno normalmente son identificadores de Python válidos, y también conocidos de antemano (en el momento de la codificación), el segundo enfoque tiene problemas. En los casos en que ese no sea el caso, probablemente debería buscar otro enfoque .
fuente
dict(mapping, **kwargs)
. Pensé que era cualquiera o. Nota: se copiaos.environ
sin modificarlo como lo sugirió @Daniel Burke en la respuesta actualmente aceptada, pero su respuesta es más sucinta. En Python 3.5+ incluso podrías hacerdict(**{'x': 1}, y=2, **{'z': 3})
. Ver pep 448 .puede usar en
my_env.get("PATH", '')
lugar demy_env["PATH"]
en caso de que dePATH
alguna manera no esté definido en el entorno original, pero aparte de eso, se ve bien.fuente
Con Python 3.5 puedes hacerlo de esta manera:
Aquí terminamos con una copia
os.environ
y unPATH
valor anulado .Fue posible gracias a PEP 448 (Generalizaciones adicionales de desempaque).
Otro ejemplo. Si tiene un entorno predeterminado (es decir
os.environ
) y un dict con el que desea anular los valores predeterminados, puede expresarlo así:fuente
Para establecer temporalmente una variable de entorno sin tener que copiar el objeto os.envrion, etc., hago esto:
fuente
El parámetro env acepta un diccionario. Simplemente puede tomar os.environ, agregar una clave (su variable deseada) (a una copia del dict si es necesario) y usarla como parámetro para
Popen
.fuente
os.environ['SOMEVAR'] = 'SOMEVAL'
Sé que esto ha sido respondido por algún tiempo, pero hay algunos puntos que algunos pueden desear saber sobre el uso de PYTHONPATH en lugar de PATH en su variable de entorno. He esbozado una explicación de cómo ejecutar scripts de Python con cronjobs que trata el entorno modificado de una manera diferente (que se encuentra aquí ). Pensé que sería de algo bueno para aquellos que, como yo, necesitaban un poco más de lo que esta respuesta proporcionó.
fuente
En ciertas circunstancias, es posible que solo desee transmitir las variables de entorno que su subproceso necesita, pero creo que tiene la idea correcta en general (así es como yo también lo hago).
fuente