python子进程Popen环境路径?

2023-11-23

假设有一个可执行文件和一个用于启动它的 Python 脚本,并且它们位于“兄弟”子目录中,例如

/tmp/subdir1/myexecutable
/tmp/subdir2/myscript.py

If in /tmp和跑步python subdir2/myscript.py具有可执行文件的相对路径

# myscript.py
from subprocess import Popen
proc = Popen(["../subdir1/myexecutable"])

它使OSError: [Errno 2] No such file or directory.

Python如何搜索可执行文件?它是否使用脚本的当前工作目录和/或位置?它使用 PATH 和/或 PYTHONPATH 吗?你能改变地点和方式吗subprocess.Popen搜索可执行文件?命令、可执行文件的绝对路径和相对路径是否有不同的处理方式? Linux 和 Windows 之间有区别吗?什么是shell=True or shell=False影响?


相对路径(包含斜杠的路径)永远不会在任何路径中被检查PATH, 无论你做什么。它们是相对于当前工作目录仅有的。如果需要解析相对路径,则必须搜索PATH手动。

如果你想运行一个程序相对于Python脚本的位置, use __file__然后从那里找到程序的绝对路径,然后在中使用绝对路径Popen.

在当前进程的环境变量中搜索PATH

Python 错误跟踪器中的一个问题关于 Python 如何处理裸命令(无斜杠)。基本上,在 Unix/Mac 上Popen表现得像os.execvp当争论env=None(在最后观察到并记录了一些意想不到的行为):

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

这实际上对两者都是如此shell=False and shell=True, 假如env=None。函数文档中解释了此行为的含义os.execvp:

末尾处包含“p”的变体(execlp(), execlpe(), execvp(), and execvpe())将使用PATH用于定位程序的环境变量file。当环境被替换时(使用其中之一exec*e变体,将在下一段中讨论),新环境被用作PATH多变的。

For execle(), execlpe(), execve(), and execvpe()(请注意,这些都以“e”结尾),env参数必须是用于定义新进程的环境变量的映射(这些变量用于代替当前进程的环境);功能execl(), execlp(), execv(), and execvp()都会导致新进程继承当前进程的环境。

引用的第二段意味着execvp将使用当前进程的环境变量。结合第一段引用的段落,我们推断出execvp将使用环境变量的值PATH来自当前进程的环境。这意味着Popen看看的价值PATH 就像 Python 刚推出时一样(运行的PythonPopen实例化)并且没有任何改变os.environ会帮助你解决这个问题。

另外,在 Windows 上shell=False, Popen不注意PATH根本不会,并且只会相对于当前工作目录进行查找。

What shell=True does

如果我们通过会发生什么shell=True to Popen?在这种情况下,Popen只需调用 shell:

The shell参数(默认为False) 指定是否使用shell作为程序来执行。

也就是说,Popen相当于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

换句话说,与shell=TruePython会直接执行/bin/sh,无需任何搜索(传递参数executable to Popen可以改变这一点,似乎如果它是一个没有斜杠的字符串,那么它会被Python解释为shell程序的名称来在值中搜索PATH从当前进程的环境中,即在该情况下搜索程序时shell=False如上所述)。

反过来,/bin/sh(或者我们的外壳executable)将寻找我们想要在其自己的环境中运行的程序PATH,这与PATHPython(当前进程)的,从上面短语“也就是说...”之后的代码推导出来(因为该调用有shell=False,所以这是前面已经讨论过的情况)。因此,execvp-类似的行为是我们从两者中得到的shell=True and shell=False, 只要env=None.

Passing env to Popen

那么如果我们通过了会发生什么env=dict(PATH=...) to Popen(因此定义一个环境变量PATH在将要运行的程序的环境中Popen)?

在这种情况下,新环境用于搜索要执行的程序。引用文档Popen:

If env is not None,它必须是一个定义新进程的环境变量的映射;这些用于代替继承当前进程环境的默认行为。

结合上述观察,并通过实验使用Popen, 这意味着Popen在这种情况下,其行为类似于函数os.execvpe. If shell=False, Python 在新定义的中搜索给定的程序PATH。正如上面已经讨论过的shell=True,在这种情况下,程序是/bin/sh,或者,如果程序名称与参数一起给出executable,然后在新定义的中搜索这个替代(shell)程序PATH.

另外,如果shell=True, then 壳内shell 将用来查找给出的程序的搜索路径args的值是PATH传递给Popen via env.

So with env != None, Popen搜索键的值PATH of env(如果有钥匙PATH存在于env).

传播除以下之外的环境变量PATH作为参数

关于环境变量有一个警告,除了PATH:如果命令中需要这些变量的值(例如,作为正在运行的程序的命令行参数),那么即使这些变量存在于env给予Popen,如果没有,它们将不会被解释shell=True。 这很容易避免,无需更改shell=True:将这些值直接插入list争论args被赋予Popen。 (另外,如果这些值来自Python自己的环境,则该方法os.environ.get可以用来获取它们的值)。

Using /usr/bin/env

如果您只是需要路径评估并且并不真正想通过 shell 运行命令行,并且使用的是 UNIX,我建议使用env代替shell=True, as in

path = '/dir1:/dir2'
subprocess.Popen(['/usr/bin/env', '-P', path, 'progtorun', other, args], ...)

这可以让你通过一个不同的PATH to the env过程(使用选项-P),它将使用它来查找程序。它还避免了 shell 元字符的问题以及通过 shell 传递参数的潜在安全问题。显然,在 Windows 上(几乎是唯一没有/usr/bin/env)你需要做一些不同的事情。

About shell=True

引用Popen文档:

If shell is True,建议通过args作为字符串而不是序列。

Note:阅读安全考虑使用前的部分shell=True.

意外的观察结果

观察到以下行为:

  • 这个呼吁引发了FileNotFoundError,正如预期的那样:

    subprocess.call(['sh'], shell=False, env=dict(PATH=''))
    
  • 这个调用发现sh,这是意想不到的:

    subprocess.call(['sh'], shell=False, env=dict(FOO=''))
    

    Typing echo $PATH在打开的外壳内显示PATHvalue 不为空,也不同于PATH在Python环境中。所以看来PATH确实不是从 Python 继承的(正如预期的那样,存在env != None),但是,它仍然是PATH是非空的。不知道为什么会出现这种情况。

  • 这个呼吁引发了FileNotFoundError,正如预期的那样:

    subprocess.call(['tree'], shell=False, env=dict(FOO=''))
    
  • 这发现tree,正如预期的那样:

    subprocess.call(['tree'], shell=False, env=None)
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python子进程Popen环境路径? 的相关文章

  • 使用 OpenCV 和/或 Numpy 对两个图像进行 Alpha 混合 [重复]

    这个问题在这里已经有答案了 我想将一个填充纯色的半透明矩形添加到已加载的半透明 PNG 中 这是我正在使用的输入图像示例 该图像加载了标准cv2 IMREAD UNCHANGED标志 以便完美保留 alpha 通道 该输入图像存储在imag
  • 使用 Ansible 将二进制文件添加到 PATH

    我正在尝试安装Kiex https github com taylor kiex版本管理器Elixir http elixir lang org install html使用 Ansible 的编程语言 这些是我为此使用的戏剧 name K
  • Python 子进程(ffmpeg)仅在我按 Ctrl-C 程序时启动?

    我正在尝试使用 Cygwin 和 Python 2 7 并行运行一些 ffmpeg 命令 这大概是我所拥有的 import subprocess processes set commands ffmpeg i input mp4 outpu
  • 最小二乘法拟合直线 python 代码

    我有一个由 X 和 Y 坐标组成的散点图 我想使用直线的最小二乘拟合来获得最佳拟合线 直线最小二乘拟合是指 如果 x 1 y 1 x n y n 是测量数据对 则最佳直线是y A Bx 这是我的Python代码 number of poin
  • 组和平均 NumPy 矩阵

    假设我有一个任意的 numpy 矩阵 如下所示 arr 6 0 12 0 1 0 7 0 9 0 1 0 8 0 7 0 1 0 4 0 3 0 2 0 6 0 1 0 2 0 2 0 5 0 2 0 9 0 4 0 3 0 2 0 1 0
  • 在Python中以交互方式执行多行语句

    我是 Python 世界的新手 这是我用 Python 编写的第一个程序 我来自 R 世界 所以这对我来说有点不直观 当我执行时 In 15 import math import random random random math sqrt
  • 按多个键分组并对字典列表的值进行汇总/平均值

    在Python中按多个键进行分组并对字典列表进行汇总 平均值的最Pythonic方法是什么 假设我有一个字典列表 如下所示 input dept 001 sku foo transId uniqueId1 qty 100 dept 001
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • 如何使用 Celery 多工作人员启用自动缩放?

    命令celery worker A proj autoscale 10 1 loglevel info启动具有自动缩放功能的工作人员 当创建多个工人时 me mypc projects x celery multi start mywork
  • Pandas:将 pytz.FixedOffset 应用于系列

    我有一个带有timestamp列看起来像这样 0 2020 01 26 05 00 00 08 00 1 2020 01 26 06 00 00 08 00 Name timestamp dtype datetime64 ns pytz F
  • 如何正确导入主代码和模块中同时使用的模块?

    假设我有一个主脚本 main py 它导入另一个 python 文件import coolfunctions另一个 import chores 现在 假设 Coolfunctions 也使用家务活中的东西 因此我声明import chore
  • 如何使用 django-pyodbc (ubuntu 16.04) 配置数据库设置 Django-MSSQL?

    我是 Django 新手 目前正在尝试使用另一个数据库来保存我的模型 即MS SQL 我的数据库部署在docker容器中 903876e64b67 microsoft mssql server linux bin sh c opt mssq
  • 线性同余生成器 - 如何选择种子和统计检验

    我需要做一个线性同余生成器 它将成功通过所选的统计测试 我的问题是 如何正确选择发电机的数字以及 我应该选择哪些统计检验 我想 均匀性的卡方频率测试 每代收集10 000个号码的方法 将 0 1 细分为10个相等的细分 柯尔莫哥洛夫 斯米尔
  • 根据列索引重命名 Dataframe 列

    是否有内置函数可以按索引重命名 pandas 数据框 我以为我知道列标题的名称 但事实证明第二列中有一些十六进制字符 根据我接收数据的方式 我将来可能会在第 2 列中遇到这个问题 因此我无法将这些特定的十六进制字符硬编码到 datafram
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • Python 导入非常慢 - Anaconda python 2.7

    我的 python import 语句变得非常慢 我使用 Anaconda 包在本地运行 python 2 7 导入模块后 我编写的代码运行得非常快 似乎只是导入需要很长时间 例如 我使用以下代码运行了一个 tester py 文件 imp
  • 在 Python 中访问 argparse 的参数值

    我正在尝试为我的程序设置一些简单的标志参数 但无法弄清楚如何访问它们 我有 argparser parser argparse ArgumentParser description Simple PostScript Interpreter
  • 更新 SQLAlchemy 中的特定行

    我将 SQLAlchemy 与 python 一起使用 我想更新表中等于此查询的特定行 UPDATE User SET name user WHERE id 3 我通过 sql alchemy 编写了这段代码 但它不起作用 session
  • 如何从 nltk 下载器中删除数据/模型?

    我在 python3 NLTK 中安装了一些 NLTK 包 通过nltk download 尝试过它们 但不需要它们 现在想删除它们 我怎样才能删除例如包large grammars来自我的 NLTK 安装 我不想删除完整的 NLTK 安装
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器

随机推荐

  • Google App Engine 自定义域未激活 Google 管理的 SSL

    我在 Google App Engine 上成功为我的应用程序配置了自定义域 我可以通过以下方式访问我的应用程序 http www myapp com 但是 在我的自定义域仪表板上 Google 管理的 SSL 需要很长时间才能激活 我有一
  • 一点到这条曲线的最短距离

    我需要找到多个点到以下形式的曲线的距离 f x a k bx 我的第一个选择是使用它的导数 使用导数的倒数形式的线 给出它的坐标Point并将其与原始曲线相交 最后 我们用简单的几何计算点之间的距离 这就是我通常遵循的数学过程 我需要节省时
  • 在证书上,主题AltName 中的电子邮件地址应为什么类型

    一点背景 我正在建造一个证书颁发机构使用 M2Crypto 和 Django 所以请在投票之前三思而后行 将其视为题外话 我的方法是 最终用户通过电子邮件地址进行识别 并且他们的自签名信任锚显然是由他们自己发布的 但我应该如何存储他们的 身
  • XML 中的转义双引号字符

    xml中的双引号是否有转义字符 我想写一个标签 例如
  • 最短超串搜索的更有效算法

    我下面的问题是 NP 完全的 但是 我试图找到至少稍微快一点的字符串搜索函数或模块 与现在相比 它可能有助于减少一些计算时间 任何建议 将不胜感激 连接的 尽可能长的 超字符串是 AGGAGTCCGCGTGAGGGAGGTGTAGTGTAG
  • 如何在 python 中构造列表项的集合?

    我有一个listpython 中的文件名 我想构造一个set从所有文件名中 filelist for filename in filelist set filename 这似乎不起作用 怎么能做到这一点呢 如果您有一个可哈希对象的列表 文件
  • 为什么分支名称不能在开头包含“#”字符?

    这个 git checkout b 1 my awesome feature 产生错误 error switch b requires a value 用反斜杠转义或用引号括起来都可以 git checkout b 1 my awesome
  • 在 Symfony2 中验证密码

    我正在尝试在 Symfony2 中整合更改密码功能 我有一个 当前密码 字段 一个 新密码 字段和一个 确认新密码 字段 我当前关注的部分是验证 当前密码 字段 顺便说一句 我现在意识到像这样的事情FOSUserBundle存在 可以为我处
  • 如何在 Laravel 5+ 中获取客户端 IP 地址

    我正在尝试在 Laravel 中获取客户端的 IP 地址 在 PHP 中使用以下命令可以轻松获取客户端的 IP SERVER REMOTE ADDR 它在核心 PHP 中工作正常 但是当我在 Laravel 中使用相同的东西时 它返回服务器
  • 在浏览器下载中保留 UTF-8 BOM

    我有一个 JAX RS REST Service 它生成 CSV 文件并将其流回浏览器 一切都设置为 UTF 8 所以我通过浏览器下载的文件也是一个有效的 UTF 8 文件 没有 BOM 它在 Notepad Sublime 等中向我显示有
  • java.lang.IllegalArgumentException:当前应该 >= start 且 <= end

    我正在尝试在 android 中的按钮上实现日期选择器 但一旦我点击按钮 错误就会弹出 但时间选择器运行良好 这是代码 mPickDate setOnClickListener new View OnClickListener Assign
  • 从 ggplot2 图例中删除“点”元素

    示例代码 EmigProb lt c rep seq 0 1 0 8 length 5 4 rep seq 0 1 0 8 length 5 4 RemainEmigProb lt c rep 0 2 5 rep 0 4 5 rep 0 6
  • Python 中基于 Web 的聊天服务器的教程 [已关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在做一个网络课程的家庭作业项目 我们必须用 C C 或 Python 构建一个简单的基于 Web 的聊天服务器 我选择 Python 是因为我认
  • AVCaptureSession stopRunning 方法会造成严重的挂起

    Using iOS 7 教程第 22 章中的 Raywenderlich 二维码阅读器 我成功读取当前应用程序的二维码 我现在扩展它 在成功读取二维码后 我想存储stringValue of the AVMetadataMachineRea
  • 间隔顺序统计

    给定一个数字数组a 0 a 1 a n 1 我们得到这样的查询 output k 范围内的最大数字a i a i 1 a j 这些问题能否在多对数时间内得到回答 在n 每个查询 如果不是 是否有可能对结果进行平均并仍然获得良好的摊余复杂度
  • 具有直接像素访问的 Opencv 颜色映射

    我有一个灰度图像 我想通过将灰度值映射到调色板 如 Matlab 中的颜色图 来以彩色显示 我设法使用 OpenCV 做到了cvSet2D函数 但出于性能原因我想直接访问像素 但当我这样做时 图像有奇怪的颜色 我尝试以不同的顺序设置颜色 R
  • WPF 中文本框中的 ScrollToCaret 位于何处?

    我无法找到该功能 基本上我有一个多行文本框 当我执行搜索时 我会突出显示结果 但是 如果结果不在视图中 我将不得不手动向下滚动 直到找到突出显示的结果 这超出了 查找 功能的目的 我不想使用 RichTextBox 因为我遇到了一些性能问题
  • PHP PDO 获取 null

    如何检查列值是否为空 示例代码 db DBCxn getCxn sql SELECT exercise id author id submission result submission time total rating votes to
  • 单击按钮时呈现部分视图

    我有索引视图 using System Web Mvc Html model MsmqTestApp Models MsmqData Scripts jquery unobtrusive ajax min js type text java
  • python子进程Popen环境路径?

    假设有一个可执行文件和一个用于启动它的 Python 脚本 并且它们位于 兄弟 子目录中 例如 tmp subdir1 myexecutable tmp subdir2 myscript py If in tmp和跑步python subd