Python 我如何告诉POpen使用/设置某些环境变量?
我正在使用Python3.7和Django。我使用下面的命令来运行通常在shell中运行的命令Python 我如何告诉POpen使用/设置某些环境变量?,python,django,python-3.x,environment-variables,popen,Python,Django,Python 3.x,Environment Variables,Popen,我正在使用Python3.7和Django。我使用下面的命令来运行通常在shell中运行的命令 out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE) t = out.communicate()[0], out.returncode 他的父亲死于错误 b'env: node: No such file or directory\n' 我试图弄清楚的是,如何让Python环境访问我可以
out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE)
t = out.communicate()[0], out.returncode
他的父亲死于错误
b'env: node: No such file or directory\n'
我试图弄清楚的是,如何让Python环境访问我可以访问的普通环境变量,或者在运行Python命令之前找到一种设置这些变量的方法。通常,当我自己检查时,很容易找到节点
davea$ which node
/usr/local/bin/node
但是我不知道如何告诉Python使用我可以访问的相同路径。如果我们参考,我们可以看到三个相关参数:
cwd str或类似路径的对象,即当前工作目录
env映射,比如dict,它是传递给被调用程序的环境映射
shell标志,无论是否将程序包装在shell中
让我们回顾一下每个解决方案
如果您负担得起,只需使用cwd=where is node,例如,如果节点位于/usr/local/bin中,您可以只使用cwd=/usr/local/bin或cwd=os.path.joinUSR\u local,“bin”。但是,所有内容都将在该文件夹中创建,这可能不是您希望在当前工作目录中创建日志、假设的内容
现在,关于环境:
如果env不是None,则它必须是定义新流程的环境变量的映射;它们被用来代替继承当前进程环境的默认行为。它直接传递给波本
您可以通过os.environ复制当前环境,并在路径中添加如下内容:
新建_env=os.environ.copy
new_env['PATH']='{}:/usr/local/bin.formatnew_env['PATH']
然后通过这个新的_env映射,您就在这里了
如果您真的想依赖shell,您可以,但以下是平台的详细信息:
POSIX平台
在shell=True的POSIX上,shell默认为/bin/sh。如果args是字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示下键入时的格式完全相同。例如,这包括引用或反斜杠转义文件名,其中包含空格。如果args是一个序列,则第一项指定命令字符串,任何附加项都将被视为shell本身的附加参数。也就是说,Popen做的等价物是:Popen['/bin/sh','-c',args[0],args[1],…]
Windows平台
在shell=True的Windows上,COMSPEC环境变量指定默认shell。在Windows上唯一需要指定shell=True的时间是您希望执行的命令内置到shell中时,例如dir或copy。运行批处理文件或基于控制台的可执行文件不需要shell=True
您可以使用PATH=whatever之类的东西,直接使用整个shell fu,但需要注意的是:安全考虑
奖金方案
只需在调用Python进程之前重新定义路径。如果您使用的是Django,则可以使用:
开发服务器
生产级服务器
在这两种情况下,您所要做的就是重新定义父流程的环境,对于生产级服务器(如Gunicorn),这是可能的,并且有文档可以完成。对于开发服务器,在您自己的shell级别执行此操作,但警告!您可能必须记录此类行为,或者告诉使用您的软件的任何人您假设节点位于路径中,这在大多数情况下是公平的。如果我们参考,我们可以看到三个相关参数:
cwd str或类似路径的对象,即当前工作目录
env映射,比如dict,它是传递给被调用程序的环境映射
shell标志,无论是否将程序包装在shell中
让我们回顾一下每个解决方案
如果您负担得起,只需使用cwd=where is node,例如,如果节点位于/usr/local/bin中,您可以只使用cwd=/usr/local/bin或cwd=os.path.joinUSR\u local,“bin”。但是,所有内容都将在该文件夹中创建,这可能不是您希望在当前工作目录中创建日志、假设的内容
现在,关于环境:
如果env不是None,则它必须是定义新流程的环境变量的映射;它们被用来代替继承当前进程环境的默认行为。它直接传递给波本
您可以通过os.environ复制当前环境,并在路径中添加如下内容:
新建_env=os.environ.copy
new_env['PATH']='{}:/usr/local/bin.formatnew_env['PATH']
然后通过这个新的_env映射,您就在这里了
如果您真的想依赖shell,您可以,但以下是平台的详细信息:
POSIX平台
在shell=True的POSIX上,shell默认为/bin/sh。如果args是字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示下键入时的格式完全相同。例如,这包括引用或回溯
斜杠转义文件名,其中包含空格。如果args是一个序列,则第一项指定命令字符串,任何附加项都将被视为shell本身的附加参数。也就是说,Popen做的等价物是:Popen['/bin/sh','-c',args[0],args[1],…]
Windows平台
在shell=True的Windows上,COMSPEC环境变量指定默认shell。在Windows上唯一需要指定shell=True的时间是您希望执行的命令内置到shell中时,例如dir或copy。运行批处理文件或基于控制台的可执行文件不需要shell=True
您可以使用PATH=whatever之类的东西,直接使用整个shell fu,但需要注意的是:安全考虑
奖金方案
只需在调用Python进程之前重新定义路径。如果您使用的是Django,则可以使用:
开发服务器
生产级服务器
在这两种情况下,您所要做的就是重新定义父流程的环境,对于生产级服务器(如Gunicorn),这是可能的,并且有文档可以完成。对于开发服务器,在您自己的shell级别执行此操作,但警告!您可能必须记录这种行为,或者告诉使用您的软件的任何人您假设节点位于路径中,这在大多数情况下是公平的。os.environ.copy最适合您所寻找的
import subprocess, os
my_env = os.environ.copy()
out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE, env=my_env)
t = out.communicate()[0], out.returncode
就这样 os.environ.copy最适合您的需要
import subprocess, os
my_env = os.environ.copy()
out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE, env=my_env)
t = out.communicate()[0], out.returncode
就这样 这就是你想要的吗?代码是如何运行的?它是在uwsgi服务器下运行还是在其他情况下运行?settings.SELENIUM\u RUNNER\u CMD和file\u path的值是多少?@kmark,SELENIUM_RUNNER_CMD是/usr/local/bin/SELENIUM side RUNNER,file_path是.side文件的绝对路径,例如/tmp/myrecording.sideOS.getenv'path'在python程序中包含/usr/local/bin吗?这就是您要寻找的吗?代码是如何运行的?它是在uwsgi服务器下运行还是其他什么?settings.SELENIUM\u RUNNER\u CMD和file\u path的值是什么?@kmark,SELENIUM\u RUNNER\u CMD是/usr/local/bin/SELENIUM side RUNNER,file\u path是.side文件的绝对路径,例如/tmp/myrecording.side os.getenv'path在python程序中是否包含/usr/local/bin?