Python中能否通过read_text()获取Shell脚本变量解析后的实际值
结论
read_text() 方法不可能拿到Shell脚本变量解析后的内容。这个方法本质就是按指定编码把文件的原始字节转成字符串返回,既不会执行Shell脚本,也不会实现Shell那套变量展开、转义解析的逻辑,读出来的永远是你写在文件里的原始文本。
可用实现方式
方案1:调用Shell解释器执行脚本后取值(推荐,适配所有合法Shell语法)
变量解析本来就是Shell解释器的原生能力,与其自己在Python里重复造轮子写解析逻辑(很容易漏了转义、命令替换、嵌套引用等各种边界情况),不如直接通过subprocess调Shell加载脚本,再把目标变量的值打印出来拿结果,兼容性最好。
示例代码:
import subprocess # 启动sh进程,先加载test.sh,再输出text变量的内容 res = subprocess.run( ["sh", "-c", "source ./test.sh && echo -n \"$text\""], capture_output=True, text=True, check=True ) parsed_text = res.stdout print(parsed_text) # 直接得到 HELLO WORLD
安全提示:这个方案会完整执行test.sh里的所有代码,如果脚本来源不可信、包含恶意命令,会直接在本机运行带来风险,只能用在你完全信任、可控的脚本场景。
方案2:简单场景自行写解析逻辑(不推荐,适配性极差)
如果你的Shell脚本非常简单,只有最基础的变量名=字符串值、$变量名引用,没有注释、转义、命令替换、条件判断这些复杂写法,也可以自己写正则逐行匹配赋值、替换变量引用,但只要脚本稍微加一点复杂语法,这个逻辑就会解析错误。
简单示例:
import re from pathlib import Path var_dict = {} for line in Path("test.sh").read_text().splitlines(): line = line.strip() # 跳过空行、注释、shebang行 if not line or line.startswith("#"): continue # 匹配最基础的赋值格式 assign_match = re.match(r"^(\w+)=\"?([^\"]*)\"?$", line) if not assign_match: continue var_name, var_val = assign_match.groups() # 替换值里已经解析过的变量引用 for exist_name, exist_val in var_dict.items(): var_val = var_val.replace(f"${exist_name}", exist_val) var_dict[var_name] = var_val print(var_dict["text"]) # 简单场景下输出HELLO WORLD
内容的提问来源于stack exchange,提问作者Georges Ordinateur
相关产品推荐
相关产品推荐

