使用Popen在Python中设置环境变量
我想通过python脚本在linux终端中设置一个环境变量。当使用使用Popen在Python中设置环境变量,python,environment-variables,subprocess,Python,Environment Variables,Subprocess,我想通过python脚本在linux终端中设置一个环境变量。当使用os.environ['BLASTDB']='/path/to/directory'时,我似乎能够设置环境变量 但是,我最初尝试使用subprocess.Popen设置此变量,但没有成功 import subprocess import shlex cmd1 = 'export BLASTDB=/path/to/directory' args = shlex.split(cmd1) p = subprocess.Popen(ar
os.environ['BLASTDB']='/path/to/directory'
时,我似乎能够设置环境变量
但是,我最初尝试使用subprocess.Popen
设置此变量,但没有成功
import subprocess
import shlex
cmd1 = 'export BLASTDB=/path/to/directory'
args = shlex.split(cmd1)
p = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
为什么subprocess.Popen
无法将环境变量BLASTDB设置为“/path/to/directory”
注:
在使用以下各项时,此操作也会失败:
import os
os.system('export BLASTDB=/path/to/directory')
使用
env
参数设置子流程的环境变量:
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
env={'BLASTDB': '/path/to/directory'})
Per:
如果env不是None,则它必须是定义环境的映射
新流程的变量;它们被使用而不是继承
当前进程的环境,这是默认行为
注:如果指定,env必须提供程序所需的任何变量
执行。在Windows上,为了并行运行程序集
指定的环境必须包含有效的SystemRoot
os.environ
可用于访问python进程的当前环境变量。如果您的系统也支持,则os.environ
也可用于设置环境变量(因此可代替上面显示的Popen的env
参数)。但是,对于某些操作系统,如FreeBSD和MacOS,设置os.environ
,因此设置os.environ
不是一个可靠的解决方案
os.system('export BLASTDB=/path/to/directory')
运行一个子流程,该子流程仅为该子流程设置BLASTDB
环境变量。由于该子进程结束,因此它对后续的subprocess.Popen
调用没有影响 据我所知,您无法从子流程或子shell(无论是Python还是bash本身)真正修改执行流程的环境。环境变量特定于您所在的特定进程(至少在您似乎正在使用的Unix上)
生成的任何子进程通常都将继承该环境,但只继承该环境的一个副本。例如,如果从终端会话内部运行
bash
,并导出一个新的环境变量,一旦退出该子shell,原始shell将保持不变。运行Python也不例外。我相信OP正在尝试为正在执行的终端/through/Python设置环境变量。您的回答将只为子流程本身设置环境变量。@Dologan:即使是这样,设置环境变量的唯一目的也是影响后续子流程调用,在这种情况下,使用env
就是答案。@unutbu:从我的测试来看env
效果很好,可以临时为特定的子流程设置环境变量BLASTDB
,一切都进展顺利。谢谢就我而言,这就足够了。os.environ很好,因为它似乎为整个python子shell设置了环境变量,并且在每个子进程中指定env
。Popen
不是必需的。实际上,根据的文档,它可以用于修改当前进程的环境(如果os提供putenv
系统调用)@Bakuriu,在某些操作系统上,所以这不是一个可靠的解决方案。但是谢谢你的评论;我更新了我的答案来澄清这一点。注意:Popen
不执行shellexport
是一个内置的shell,因此如果您尝试运行该命令,将出现“文件未找到错误”。使用shell=True
执行shell命令(并注意它的安全风险!!!)从我的测试来看,即使将shell=True
添加到命令中,它实际上也不会更改执行python脚本的环境变量,它也不会更改在执行时创建的python子shell的环境变量。这可能只会改变这一特定子流程的环境,这(如果没有添加env
)将不允许我在该子流程的修改环境下对终端执行命令。我从未说过shell=True
会解决您的问题(否则我会将其作为答案发布)。使用shell=True
是能够运行shell命令的先决条件。如果没有它,您将收到错误,因为Popen
无法找到可执行文件。同意,我试图向未来的访问者澄清我的具体问题。到目前为止,我还无法修改执行过程的环境。对我来说,我只需要对特定的子流程命令进行临时调整。然而,我很好奇这是否可能。感谢您提供的信息。可以通过env关键字arg到subprocess.Popen,如unutbuth的答案所示。原始问题表明OP希望为linux终端本身设置环境变量,而不仅仅是为从Python本身执行的子进程设置环境变量。在这种情况下,据我所知,我的答案仍然是有效和正确的。