2

我目前正在尝试使用 python 为我的团队编写一些组件测试,我遇到了一个测试过程,它告诉测试人员获取一个 csh 文件。这个文件有一堆 setenv 命令和别名。链中的下一个可执行文件需要所有这些环境变量。我想设计一些方法来提取所有环境变量并将它们传递给链中的下一个进程。

我查看了以下问题,这几乎是我所需要的: Emulating Bash 'source' in Python

它将所有导出的 bash 环境变量推送到字典中,然后我可以将其传递给下一个进程。问题是这似乎只适用于csh 命令export,而不适用于 cshsetenv命令。

如果这是不可能的,有没有办法使用子进程命令运行 .csh 文件,/bin/sh -c script.csh然后运行需要这些环境变量的进程作为该进程的子进程(以便它可以继承它的环境变量?)

本质上,我有一个进程和脚本,其中包含一堆 setenv 变量,并且该进程需要在包含所有这些环境变量的环境中运行。

谢谢你的帮助,

4

4 回答 4

1

您是否考虑过John Kugelman 的解决方案?那将是最简单的方法。

但是,如果出于某种原因您需要或希望 Python 成为这些脚本之间的中介,那么您可以使用以下内容来获取脚本并检索环境变量。(编辑:感谢 abarnert 和 Keith Thompson 的正确csh命令。)

如果script.csh包含

setenv foo bar

然后

import subprocess
import os
import json
PIPE = subprocess.PIPE
output = subprocess.check_output(
    '''source script.csh; python -c "import os, json; print(json.dumps(dict(os.environ)))"''',
    shell=True, executable='/bin/csh')
env = json.loads(output)
print(env['foo'])

产量

bar
于 2013-05-24T22:28:32.217 回答
0

最简单的方法是让csh源设置脚本,然后运行其他脚本。例如:

设置.csh:

setenv foo bar

脚本.csh:

echo $foo

亚军.py:

import subprocess
csh_command = 'source ./setup.csh && ./script.csh'
subprocess.check_call(['/bin/csh', '-c', csh_command])

如果您只想使用链接问题中的代码,您所要做的就是更改正则表达式。只需替换exportsetenv,=\s+

于 2013-05-24T22:50:39.990 回答
0

所以script.csh包含setenv设置某些环境变量的命令。

/bin/sh -c script.csh只会执行脚本;脚本完成后,环境变量将丢失。即使这样也假设它script.csh是可执行的;如果它应该被采购,它不需要,而且可能不应该是。

要使环境变量设置可见,script.csh必须由 csh 进程获取。

这是一个粗略的大纲:

/bin/csh -c 'source script.csh ; python -c ...'

python -c ...进程将能够看到环境变量。执行上述命令的进程不会。

一个更复杂的解决方案是这样的:

printenv > before.txt
/bin/csh -c 'source script.csh ; printenv' > after.txt

然后进行比较before.txtafter.txt看看环境发生了什么变化。(或者您可以通过其他方式捕获输出。)这样做的好处是可以让调用进程看到修改后的环境,或者至少获得有关它的信息。

请注意,在某些不寻常的情况下,您可能无法从printenv. 例如,如果值为$FOO"10\nBAR=20"那将在输出中显示printenv为:

FOO=10
BAR=20

看起来像$FOOis10$BARis 20。(在环境变量值中有换行符实际上并不少见;我$TERMCAP的当前设置为 21 行文本块。

您可以通过编写自己的printenv替换来避免这种情况,该替换打印环境的明确表示。

于 2013-05-24T22:54:37.237 回答
0

这适用于我从 shell 脚本(调用其他 shell 脚本)获取环境。您可以执行类似的操作将环境读入字典,然后使用 os.environ 更改环境。

    导入子流程

    SAPENVCMD = "/bin/csh -c \'source ~/.cshrc && env\'"
    envdict = {}

    def 运行命令(命令):
        ps = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        out,err = ps.communicate()
        outlist = out.split('\n')
        如果 ps.returncode == 0:
           退货清单
        别的:
           返回无

    def elist2dict(字典,列表):
        对于列表中的条目:
            如果条目不是无:
               pos = entry.find('=')
               键 = 条目[:pos]
               位置 += 1
               值 = 条目 [位置:]
               dict.setdefault(键,值)

    def env2dict(字典,ENVCMD):
        envlist = 运行命令(ENVCMD)
        elist2dict(字典,envlist)


    env2dict(envdict,SAPENVCMD)

    v = envdict["SAPSYSTEMNAME"]
    打印 v


于 2018-11-07T16:30:16.103 回答