Windows正常运行的Python脚本在Linux运行时JSON解析报错求助
问题描述
原本在Windows系统运行正常的Python脚本,部署到Linux/Ubuntu机器后,已修改路径参数、将解释器改为python3,但调用API的函数出现错误。该函数通过subprocess调用另一个带JSON参数的Python脚本并读取输出,代码如下:
script_path = "/home/user/some_path_here/filename" def ReportsByDate(date = today): new_report = subprocess.Popen([ "python3", script_path, "reports/list", json.dumps({"date": today}), "pretty", ], shell=True, stdout=subprocess.PIPE) output = new_report.communicate()[0] output = json.loads(output) global df df = pd.DataFrame(output) return(df)
运行时触发以下错误:
Traceback (most recent call last): File "prod_get_today.py", line 118, in <module> ReportsByDate() File "prod_get_today.py", line 72, in ReportsByDate output = json.loads(output) File "/usr/lib/python3.8/json/__init__.py", line 357, in loads return _default_decoder.decode(s) File "/usr/lib/python3.8/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
用户猜测可能的原因:
- 解释器调用不正确
- Linux与Windows下读取shell数据的方式不同
问题原因及解决办法
核心原因
错误提示JSONDecodeError: Expecting value说明output为空或不是有效JSON,主要问题出在subprocess的参数使用和输出捕获逻辑上:
shell=True破坏参数结构:Linux下启用shell=True时,列表形式的参数会被拼接成字符串交给shell解析,JSON字符串里的引号、空格会被shell拆分,导致被调用脚本无法正确接收参数,进而无输出或输出错误内容。- 未捕获错误输出:被调用脚本可能因权限不足、路径错误、依赖缺失等问题在Linux下执行失败,但当前代码只捕获
stdout,错误信息输出到stderr未被获取,无法排查实际问题。 - 编码与字节处理问题:
subprocess.communicate()返回的是bytes对象,直接用json.loads()解析可能因编码不匹配出错,不过空输出是本次报错的直接诱因。
解决步骤
- 移除
shell=True(推荐方案)
无需shell特性时,直接用列表传递参数,避免shell解析破坏参数:
new_report = subprocess.Popen( ["python3", script_path, "reports/list", json.dumps({"date": today}), "pretty"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, # 同时捕获错误输出 encoding="utf-8" # 指定编码,直接返回字符串而非bytes )
- 捕获并检查错误输出
调用communicate()后同时获取stdout和stderr,排查被调用脚本的执行问题:
output, error = new_report.communicate() if error: print(f"脚本执行错误: {error}") # 可添加错误处理逻辑 if not output: print("脚本无输出") # 处理无输出场景 output = json.loads(output)
- 验证被调用脚本的可执行性
- 给目标脚本添加可执行权限:
chmod +x /home/user/some_path_here/filename - 直接在终端运行脚本,检查是否能正常输出JSON:
python3 /home/user/some_path_here/filename reports/list '{"date": "2024-05-20"}' pretty(替换为实际日期值)
- 确认解释器路径正确性
若系统存在多个Python版本,使用绝对路径调用解释器,比如/usr/bin/python3或虚拟环境内的解释器路径,确保调用的是依赖匹配的环境。
内容的提问来源于stack exchange,提问作者Prometheus
相关产品推荐
相关产品推荐

