soword科技言
永久公益免费API接口
提供永久免费的API接口,查看更多API接口,如果您有其他免费API资源,请联系我们,造福人类。
提供商务开发:小程序,系统,APP
定制开发,免费评估,免费咨询,价格便宜,售后保障,前往开发服务中心联系开发客服中心
为什么子进程忽略PATH,如何更改它?

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

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

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

创建test.py

import osfrom 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因为调用subprocess文件指出,

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

不用说,从C调用实际 execvp POSIX API 确实尊重PATH,因此这是Python特有的问题。


1 Ubuntu 18.04.2 LTS,Python 3.6.9。

根据我的评论,这是由于Python的实现execvp与POSIX execvp语义不一致特别是Python 不会ENOEXEC通过将文件解释为Shell脚本来对错误做出响应,并且需要显式的shebang。

创建文件为:

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

使事情按预期工作

你的

echo 'echo foobar' >whoami
chmod +x whoami

运行不正常。

即使设置了执行位,Python也不选择可执行文件,它不知道它需要先运行bash才能执行,因此它会跳过该路径并运行路径为/ usr的原始whoami。 / bin / whoami

添加shebang

echo "#!/bin/sh" > whoami
echo 'echo foobar' >> whoami
chmod +x whoami

在Unix风格的系统(包括Linux / OS X)上,shebang线(称为)告诉加载程序(或内核,或有时是shell)使用哪个程序来运行文件。最基本的说,您将指定python解释器的路径。

我怀疑如果您./whoami(设置了执行权限),则外壳程序正在执行一些额外的操作,因此您不必键入/ bin / sh $ PWD / whoami

如果你这样做

chmod -x whoami

你可以用特殊的

./whoami(告诉外壳程序将其作为外壳程序脚本执行)。

注意execvp应该使用/ bin / sh而不是bash。也。./whoami将取决于您恰巧使用的Shell,大多数将“提供”文件而不是在另一个进程中执行(例如,对环境,工作目录等的更改将保留)

如果没有shebang或可执行文件头,则外壳程序仅将其自身用作默认解释器(但仅当通过./whoami;。./whoami进行调用时,无论文件是否可执行,它都会提供文件)。

execvp(POSIX,而不是Python)的混乱特性显然也可以做到这一点。在这种情况下,Python会失败,因为os.execvp实际上并未在幕后调用execvp,其相似之处仅在于名称。



2023-03-22 10:04:19

新人小程序+APP定制199元起


发放福利,助力中小企业发展,真正在互联网中受益

点击询问定制

广告服务展示