wim*_*wim 56 python environment subprocess path popen
我对subprocess
使用时如何搜索可执行文件感到困惑Popen()
.如果给定子进程的绝对路径,它可以工作,但我正在尝试使用相对路径.我发现如果我设置环境变量PYTHONPATH然后我可以从该路径获得导入的模块,并且PYTHONPATH存在sys.path
,但它似乎没有帮助的行为subprocess.Popen
.我也尝试过编辑sitecustomize.py
添加PYTHONPATH 的文件os.environ
,就像这样
# copy PYTHONPATH environment variable into PATH to allow our stuff to use
# relative paths for subprocess spawning
import os
if os.getenv('PYTHONPATH') is not None and os.getenv('PATH') is not none:
os.environ['PATH'] = ':'.join([os.getenv('PATH'), os.getenv('PYTHONPATH')])
Run Code Online (Sandbox Code Playgroud)
并且验证了在启动python时,无论是交互式地,使用ipython,还是通过从命令行运行脚本,PYTHONPATH都成功出现os.environ
.但是,subrocess.Popen
仍然不在那里搜索可执行文件.如果没有env
指定kwarg ,我认为它应该继承父母的环境?接下来我尝试env
明确地给出,首先通过制作副本,os.getenv
然后仅仅通过给予env={'PATH': '/explicit/path/to/search/from'}
,它仍然找不到可执行文件.现在我很难过.
希望一个例子可以帮助我更清楚地解释我的问题:
/ dir/subdir1/some_executable
/dir/subdir2/some_script.py
# some_script.py
from subprocess import Popen, PIPE
spam, eggs = Popen(['../subdir1/some_executable'], stdout=PIPE, stderr=PIPE).communicate()
Run Code Online (Sandbox Code Playgroud)
如果我在/dir/subdir2
,我运行python some_script.py
它的工作,但如果我在/dir
,我运行python subdir2/some_script.py
即使/dir/subdir2
在os.environ['PATH']
,然后子进程将抛出OSError: [Errno 2] No such file or directory
.
Wal*_*ndt 60
(从评论中填写详细信息以单独回答)
首先,无论你做什么,都不会在任何路径中检查相对路径(包含斜杠的路径).它们仅与当前工作目录相关.如果需要解析相对路径,则必须手动搜索PATH,或者使用PATH来包含子目录,然后使用命令名称,如下面的建议所示.
如果要运行相对于Python脚本位置的程序,请使用__file__
并从那里查找程序的绝对路径,然后使用绝对路径Popen
.
其次,Python bug跟踪器中存在一个问题,即Python如何处理裸命令(没有斜杠).基本上,在Unix/Mac上Popen
使用os.execvp
时调用shell=False
,这意味着它会查看PATH
Python启动时的值,并且没有任何更改os.environ
可以帮助您解决这个问题.此外,在Windows上shell=False
,它根本不关注PATH,只会查看相对于当前工作目录的内容.
如果你只是需要路径评估而不是真的想通过shell运行你的命令行,并且在UNIX上,我建议使用env
而不是shell=True
像在Popen(['/usr/bin/env', 'progtorun', other, args], ...)
.这允许您将不同的PATH传递给env
进程,该进程将使用它来查找程序.它还避免了shell元字符的问题以及通过shell传递参数的潜在安全问题.显然,在Windows上(几乎是没有a的唯一平台/usr/bin/env
),你需要做一些不同的事情.
nco*_*lan 12
你似乎对PATH
and 的本质有点困惑PYTHONPATH
.
PATH
是一个环境变量,告诉OS shell在哪里搜索可执行文件.
PYTHONPATH
是一个环境变量,告诉Python解释器在哪里搜索要导入的模块.它与subprocess
查找可执行文件无关.
由于底层实现的不同,subprocess.Popen
默认情况下只会在非Windows系统上搜索路径(Windows总是会搜索一些系统目录,但这与PATH
处理不同).扫描路径的唯一可靠的跨平台方法是传递shell=True
给子进程调用,但这有其自身的问题(如Popen
文档中所详述)
但是,看起来您的主要问题是您正在传递路径片段Popen
而不是简单的文件名.只要你有一个目录分隔符,你就会禁用PATH
搜索,即使在非Windows平台上也是如此(例如,请参阅exec系列函数的Linux文档).
归档时间: |
|
查看次数: |
59266 次 |
最近记录: |