2017-04-19 160 views
0

我使用一个代码执行bash脚本,定义了很多环境变量的环境变量:执行bash脚本,定义使用Python

#!/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 

我的/ home /用户/ env_file的含量下一个:

#!/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代码时,我没有得到my_dir变量的任何值。我该如何执行此操作?

此致敬礼。

+1

程序只能更改自身及其子项的环境变量,而不是启动它的程序的环境变量。因此,从Python解释器开始的bash脚本不能为该Python解释器设置变量。 –

+0

由于子进程无法更改其父环境,因此无法执行脚本来执行此操作。您需要编写读取脚本的Python代码,解析分配,然后分配给'os.environ'。 – Barmar

+0

@Barmar,... wellll。我不愿意鼓励某人编写自己的shell解析器 - 这条道路上有许多陷阱。我正在开始在shell中实现的一个答案,该答案会生成一个任意脚本,并将所有在执行结束时出现的环境变量写入NUL分隔格式的stdout中。 –

回答

0

一个过程来影响其父母的环境(没有丑陋的黑客滥用的开发/调试工具)的唯一方法是与父进程的直接参与(这就是为什么一个运行eval "$(ssh-agent)" - eval荷兰国际集团它的输出,在这种情况下, ,父级需要合作,让ssh-agent在启动它的过程中设置环境变量)。请看下面的外壳包装:

#!/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 "[email protected]"   # 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) 

...从下面的Python叫:

import subprocess, itertools, os 

ps = subprocess.Popen(['envvar-extraction-wrapper', '/home/user/env_file'], 
         stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
(stdout, stderr) = ps.communicate() 
items_iter = iter(stdout.split('\0')) 
for (k,v) in itertools.izip(items_iter, items_iter): 
    os.environ[k]=v 
0

的bash脚本,env_file在自己的进程中执行,从而改变了这里的环境变量不会反射回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 

本hack涉及重复env_file的内容复制到另一个临时文件,然后在重复文件的末尾添加一个echo语句,执行它,并收集输出。

另外,我的假设是原始脚本不输出任何内容。如果是这样,你必须解析输出并找到你正在寻找的东西。