python - 为什么子进程忽略 PATH,我该如何更改它?

标签 python linux path subprocess

我需要更改 Python 应用程序调用的程序。不幸的是,我无法更改 Python 代码。我只能更改调用环境(特别是 PATH)。但不幸的是,Python 的子进程模块似乎忽略了 PATH(至少在某些情况下)。

在搜索要调用的二进制文件时,如何强制 Python 遵循 PATH

为了说明问题,这里有一个 MVCE。实际的 Python 应用程序正在使用 subprocess.check_output(['nvidia-smi', '-L']),但以下简化代码显示了相同的行为。

创建test.py:

import os
from subprocess import run

run(['which', 'whoami'])
run(['/usr/bin/env', 'whoami'])
run(['whoami'])

os.execvp('whoami', ['whoami'])

现在创建一个本地whoami脚本并执行test.py:

echo 'echo foobar' >whoami
chmod +x whoami
PATH=.:$PATH python3 test.py

在我的系统1 上打印:

./whoami
foobar
konrad
konrad

期望这段代码总是打印foobar而不是konrad

我的 MVCE 包含 os.execvp 调用,因为 the subprocess documentation指出

On POSIX, the class uses os.execvp()-like behavior to execute the child program.

不用说,实际 execvp POSIX API,从 C 调用,确实尊重PATH,所以这是一个特定于 Python 的问题。


1 Ubuntu 18.04.2 LTS,Python 3.6.9。

最佳答案

根据我的评论,这是由于 Python 对 execvp 的实现所致不符合 POSIX execvp语义。特别是 Python doesn't respond to ENOEXEC errors通过将文件解释为 shell 脚本并需要一个显式的 shebang。

将文件创建为:

printf '#!/bin/sh\necho foobar\n' > ./whoami

使事情按预期工作

请注意,这已经有一段时间了:https://bugs.python.org/issue19948

关于python - 为什么子进程忽略 PATH,我该如何更改它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62893701/

相关文章:

python - uwsgi_params 文件应该放在哪里,它的扩展名是什么?

linux - 更新到 OpenGL 3.2 英特尔赛扬 archLinux

javascript - 在 NodeJS 中使用参数获取 Express Route URL

iphone - Xcode 4——设置组的路径?

python - 从两个日期生成日期列表的最Pythonic方法是什么

python - 查找子范围列表未涵盖的较大范围的范围

Python:使用数组作为另一个数组的条件

ruby-on-rails - 生成不生成代码

java - JRE 经常崩溃。我在 Linux 中将 RXTX 与 Java (1.6) 用于串行通信。异常(exception)

linux - 我如何在 python 中获得 unix 中的最大文件系统路径长度?