Python传含#等特殊字符环境变量调用mssql-cli时登录失败
问题原因
- 环境变量名不匹配:你执行导出时设置的环境变量名为
password,但Python代码中读取的是target_env变量,实际读取到的密码值为None,转字符串后为"None",和真实密码不符。 - Shell特殊字符截断:你导出环境变量时没有给带特殊字符的密码加引号,
#在shell中是注释起始符,实际导出的密码值会被截断为foo],后面的#BAR不会被纳入变量值。 - 命令拼接风险:使用
os.system做字符串拼接传参,密码中的特殊字符会被shell二次解析,不仅容易出现参数传递错误,还存在命令注入风险。
修复方案
- 修正环境变量导出命令:给含特殊字符的密码加单引号包裹,同时保证环境变量名和代码中读取的键名完全一致,导出命令如下:
export target_env='foo]#BAR'
单引号会让shell原样保留引号内的所有字符,不会解析#、]等特殊符号,保证密码值完整。
- 替换
os.system调用方式,改用标准库subprocess以参数列表形式传参,跳过shell解析环节,从根源避免特殊字符转义问题,修正后的代码如下:
import os import subprocess username = 'test1' password = os.getenv('target_env') # 增加校验,避免未读到环境变量时无意义报错 if not password: raise RuntimeError("环境变量target_env未设置") database = "master" server = "xyz.com" query = "some random query" # 参数以列表形式传入,不经过shell转义 subprocess.run( [ "mssql-cli", "-U", username, "-P", password, "-d", database, "-S", server, "--query", query ], check=True )
- 调试校验:如果运行时仍有登录报错,可以先在代码中加
print(repr(password))打印读取到的密码值,确认和你设置的密码完全一致,排除值截断、读错变量的问题。
注意:原代码中拼接
-d参数时,参数名和参数值之间没有空格,部分版本的客户端可能无法识别该写法,用列表传参时分开写参数名和值可以规避这个兼容问题。
内容的提问来源于stack exchange,提问作者Hoomaan
相关产品推荐
相关产品推荐

