Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
执行使用Python定义环境变量的bash脚本_Python_Linux_Variables_Subprocess_Environment - Fatal编程技术网

执行使用Python定义环境变量的bash脚本

执行使用Python定义环境变量的bash脚本,python,linux,variables,subprocess,environment,Python,Linux,Variables,Subprocess,Environment,我将使用下一段代码执行一个bash脚本,该脚本定义了许多环境变量: #!/usr/bin/python # -*- coding: utf-8 -*- import subprocess # Code used to get the value of variable before the call to my script command = "echo $MYDIR" ps = subprocess.Popen(command, shell=True, stdout=subprocess

我将使用下一段代码执行一个bash脚本,该脚本定义了许多环境变量:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import subprocess

# Code used to get the value of variable before the call to my script
command = "echo $MYDIR"
ps = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
my_dir = ps.communicate()[0]
print "my_dir", my_dir

subprocess.Popen(["/bin/sh", "/home/user/env_file"])

# Code used to get the value of established variable
command = "echo $MYDIR"
ps = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
my_dir = ps.communicate()[0]
print "my_dir", my_dir
my/home/user/env_文件的内容如下:

#!/bin/bash

export MYDIR=/home/user
export MYDIR2=/home/user2
export MYDIR3=/home/user3
export MYDIR4=/home/user4
export MYDIR5=/home/user5
export MYDIR6=/home/user6
export MYDIR7=/home/user7
export MYDIR8=/home/user8
export MYDIR9=/home/user9
export MYDIR10=/home/user10
export MYDIR11=/home/user11
export MYDIR12=/home/user12
export MYDIR13=/home/user13
export MYDIR14=/home/user14
export MYDIR15=/home/user15
export MYDIR16=/home/user16
当我执行Python代码时,我的_dir变量没有任何值。我怎样才能做到这一点


致以最诚挚的问候。

一个进程影响其父环境的唯一途径(没有滥用开发/调试设施的丑陋黑客)是该父进程的直接参与(这就是为什么要运行
eval“$(ssh代理)”
--eval在本例中,它的输出是父级需要的合作,以允许
ssh代理在启动它的过程中设置环境变量)。考虑下面的外壳包装:

#!/usr/bin/env bash
# Save this script as "envvar-extraction-wrapper"
exec {orig_stdout}>&1 # create a backup of stdout
exec >&2              # and then use stderr while sourcing the child script

source "$@"           # run arbitrary script with arbitrary arguments *in this shell*
                      # note that this means that if it runs "exit", we abort prematurely

while read -r varname; do
  printf '%s\0%s\0' "$varname" "${!varname}" >&$orig_stdout
done < <(compgen -e)
bash脚本env_文件在它自己的进程中执行,因此这里对环境变量的更改不会反映到python脚本的进程中。如果您可以重新设计脚本以避免这种情况,那将是最好的。否则,我们不得不求助于一些黑客,这里就是其中之一

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import subprocess
import tempfile

env_file = "/tmp/env_file"
with open(env_file) as f:
    original_script_contents = f.read()

# Duplicate the env_file and add an echo statement at the end
with tempfile.NamedTemporaryFile() as temp_script:
    temp_script.write(original_script_contents)
    temp_script.write('\necho $MYDIR')
    temp_script.flush()

    my_dir = subprocess.check_output(["/bin/sh", temp_script.name])
    print 'my_dir =', my_dir
这种攻击包括将env_文件的内容复制到另一个临时文件中,然后在复制文件的末尾添加echo语句,执行它并收集输出


另外,我的假设是原始脚本没有输出任何内容。如果是这样,您必须解析输出并找到您要查找的内容。

程序只能更改自身及其子程序的环境变量,而不能更改启动它的程序的环境变量。因此,从Python解释器启动的任何bash脚本都不能为该Python解释器设置变量。您需要编写Python代码来读取脚本,解析分配,然后分配给
os.environ
@Barmar,…welll。我很犹豫是否鼓励别人编写自己的shell解析器——这条路上有很多陷阱。我目前正在使用一个在shell中实现的应答,该应答源于一个任意脚本,并将执行结束时存在的所有环境变量(在开始时不存在)以NUL分隔的形式写入标准输出。为什么要将其作为外部shell脚本来执行?为什么不直接读取python脚本中变量的名称和值呢?你真的需要shell提供的所有函数吗(从引用问题开始,以命令替换之类的东西结束)?@CharlesDuffy我的评论只适用于问题中的文本赋值。如果有任何shell逻辑,那就是一个问题。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import subprocess
import tempfile

env_file = "/tmp/env_file"
with open(env_file) as f:
    original_script_contents = f.read()

# Duplicate the env_file and add an echo statement at the end
with tempfile.NamedTemporaryFile() as temp_script:
    temp_script.write(original_script_contents)
    temp_script.write('\necho $MYDIR')
    temp_script.flush()

    my_dir = subprocess.check_output(["/bin/sh", temp_script.name])
    print 'my_dir =', my_dir