为什么子进程忽略 PATH,我该如何改变它? [英] Why is subprocess ignoring PATH, and how can I change this?

查看:35
本文介绍了为什么子进程忽略 PATH,我该如何改变它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to change which program is called by a Python application. Unfortunately I cannot change the Python code. I can only change the calling environment (in particular, PATH). But unfortunately Python’s subprocess module seems to ignore PATH (at least under certain circumstances).

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

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

To illustrate the problem, here’s an MVCE. The actual Python application is using subprocess.check_output(['nvidia-smi', '-L']), but the following simplified code shows the same behaviour.

创建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:

Now create a local whoami script and execute test.py:

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

在我的系统1上打印:

./whoami
foobar
konrad
konrad

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

I expect this code to always print foobar instead of konrad.

我的 MVCE 包括 os.execvp 调用,因为 subprocess 文档 指出

My MVCE includes the os.execvp call because the subprocess documentation states that

在 POSIX 上,该类使用类似 os.execvp() 的行为来执行子程序.

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

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

Needless to say, the actual execvp POSIX API, called from C, does respect PATH, so this is a Python specific issue.

1 Ubuntu 18.04.2 LTS,Python 3.6.9.

1 Ubuntu 18.04.2 LTS, Python 3.6.9.

推荐答案

根据我的评论,这是由于 Python 对 execvp 与 POSIX 不一致 execvp 语义.特别是 Python 不响应ENOEX代码> 错误 将文件解释为 shell 脚本并需要显式shebang.

as per my comment, this is due to Python's implementation of execvp not being consistent with POSIX execvp semantics. in particular Python doesn't respond to ENOEXEC errors by interpreting the file as a shell script and needs an explicit shebang.

创建文件为:

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

使事情按预期工作

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

note that this has been known about for a while: https://bugs.python.org/issue19948

这篇关于为什么子进程忽略 PATH,我该如何改变它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆