执行bash脚本,定义使用Python
问题描述:
我使用一个代码执行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变量的任何值。我该如何执行此操作?
此致敬礼。
答
一个过程来影响其父母的环境(没有丑陋的黑客滥用的开发/调试工具)的唯一方法是与父进程的直接参与(这就是为什么一个运行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
答
的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语句,执行它,并收集输出。
另外,我的假设是原始脚本不输出任何内容。如果是这样,你必须解析输出并找到你正在寻找的东西。
程序只能更改自身及其子项的环境变量,而不是启动它的程序的环境变量。因此,从Python解释器开始的bash脚本不能为该Python解释器设置变量。 –
由于子进程无法更改其父环境,因此无法执行脚本来执行此操作。您需要编写读取脚本的Python代码,解析分配,然后分配给'os.environ'。 – Barmar
@Barmar,... wellll。我不愿意鼓励某人编写自己的shell解析器 - 这条道路上有许多陷阱。我正在开始在shell中实现的一个答案,该答案会生成一个任意脚本,并将所有在执行结束时出现的环境变量写入NUL分隔格式的stdout中。 –