rcfile 中设置的变量无法通过 Python 访问

问题描述 投票:0回答:1

我有一个 shell 脚本和一个 python 脚本,组织如下(不能更改目录结构):

~
├── a.py
├── b
    └── c.sh

MWE如下:

c.sh

#!/bin/sh
rcfile=$(mktemp)
export TEST1='hello'
cat <<-EOF > ${rcfile}
    export TEST2='world'
EOF
${SHELL} --rcfile ${rcfile}
rm -f ${rcfile}

a.py

from subprocess import Popen, PIPE
p = Popen('./c.sh', cwd='./b', stdin=PIPE)
p.communicate(b'echo $TEST1\necho $TEST2\nexit')

当我执行 shell 脚本

c.sh
时,它会按预期显示两个变量。

enter image description here

但是,当从Python脚本

a.py
执行时,内部变量即
TEST2
未设置。

enter image description here

不能修改shell脚本。

有没有办法从Python脚本访问变量

TEST1
TEST2

python subprocess sh subshell
1个回答
0
投票

我尝试使用

pexpect
但仍然缺少第二个值 (
$TEST2
)。我怀疑这是缓冲的问题。与此同时,我想出了一个解决办法:虽然你不能修改shell脚本;您可以修改它的副本。对于我的解决方案,我将制作一个副本,修改运行 shell 的行,以便它能够

  1. 获取 rcfile
  2. 回显测试1、测试2

代码:

#!/usr/bin/env python3
import pathlib
import subprocess

# Duplicate c.sh and modify the SHELL line
original_script = pathlib.Path("./b/c.sh")
modified_script = original_script.with_stem("c-copy")
content = original_script.read_text().splitlines()

with open(modified_script, "w", encoding="utf-8") as stream:
    for line in content:
        if line.startswith("${SHELL}"):
            line = ". ${rcfile}\necho TEST1=$TEST1\necho TEST2=$TEST2"
        stream.write(f"{line}\n")

# Run
modified_script.chmod(0o777)
process = subprocess.run(
    ["./b/c-copy.sh"],
    text=True,
    capture_output=True,
)

# Clean up
modified_script.unlink()

# Parse output and print. Assume that the shell script might produce
# other output, so we only grab lines with starts with "TEST"
shell_vars = dict(
    line.split("=") for line in process.stdout.splitlines()
    if line.startswith("TEST")
)
print(shell_vars)

输出:

{'TEST1': 'hello', 'TEST2': 'world'}

我在 Fedora 40 和 Python 3.12.4 中对此进行了测试。

© www.soinside.com 2019 - 2024. All rights reserved.