python - 我如何告诉 POpen 使用/设置某些环境变量?

标签 python django python-3.x environment-variables popen

我正在使用 Python 3.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 环境能够访问我有权访问的普通环境变量,或者想出一种在运行 Python 命令之前设置它们的方法。正常情况下“节点”我自己查的时候很容易找到

davea$ which node
/usr/local/bin/node

但我不知道如何告诉 Python 使用我有权访问的相同路径。

最佳答案

如果我们引用 Popen's documentation ,我们可以看到三个相关论点:

  1. cwd strpath 类对象,即当前工作目录
  2. env 映射(假设是一个dict),这是传递给被调用程序的环境映射
  3. shell 标志,是否将程序包装在 shell 中

让我们回顾一下每个解决方案。


如果你负担得起,就使用cwd="where is node",例如,如果node/usr/local/bin,你可以只使用 cwd=/usr/local/bincwd=os.path.join(USR_LOCAL, 'bin') 例如。但是,所有内容都将在此文件夹中创建,这可能不是您想要的(日志、对当前工作目录的假设)。


现在,对于环境:

If env is not None, it must be a mapping that defines the environment variables for the new process; these are used instead of the default behavior of inheriting the current process’ environment. It is passed directly to Popen.

您可以通过 os.environ 复制您当前的环境,然后在 PATH 中添加一些内容,如下所示:

new_env = os.environ.copy()
new_env['PATH'] = '{}:/usr/local/bin'.format(new_env['PATH'])

然后传递这个 new_env 映射就可以了!


如果你真的想依赖 shell,你可以,但这里是平台细节:

POSIX 平台

On POSIX with shell=True, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of: Popen(['/bin/sh', '-c', args[0], args[1], ...])

Windows 平台

On Windows with shell=True, the COMSPEC environment variable specifies the default shell. The only time you need to specify shell=True on Windows is when the command you wish to execute is built into the shell (e.g. dir or copy). You do not need shell=True to run a batch file or console-based executable.

您可以使用类似 PATH=whatever 的东西并直接使用您的整个 shell-fu,但注意事项是:安全考虑


奖金解决方案

只需在调用您的 Python 进程之前重新定义 PATH。如果您使用的是 Django,则您正在使用:

  1. 开发服务器
  2. 生产级服务器

在这两种情况下,你所要做的就是重新定义父进程的环境,对于像 Gunicorn 这样的生产级服务器,这是可能的,并且有文档可以做到这一点。对于开发服务器,在您自己的 shell 级别执行此操作(但警告!您可能必须记录此类行为或告诉任何使用您的软件的人您假设 node 位于...最时间公平)。

关于python - 我如何告诉 POpen 使用/设置某些环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56960456/

相关文章:

python - 我如何处理 Django 中的 spotify api 身份验证重定向 uri?

Django模型继承并根据类别访问子级

python - django1.11类型错误: context must be a dict rather than RequestContext

python - 将多个 *.ts 文件(字节或类字节格式)连接到一个 mp4 文件

python - PyQt 从用户获取日期

python - 图例有多个点

python-3.x - python 错误 "TypeError: ' int' 对象不可调用”

python - 如何使第一行变成第二级MultiIndex

python - 如何仅提取多行字符串的第一行

python - 在 while 列表中添加 +=