2017-04-19 158 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語句,執行它,並收集輸出。

另外,我的假設是原始腳本不輸出任何內容。如果是這樣,你必須解析輸出並找到你正在尋找的東西。