Ubuntu环境下Python调用sudo执行subprocess报错(状态1)如何解决?
嘿,我来帮你搞定这个问题!首先明确说:这个错误确实和sudo有关,但你的代码还有几个参数使用的问题,咱们一步步来解决:
问题根源拆解
你遇到的returned non-zero exit status 1错误,主要来自两个地方:
- subprocess参数格式完全错误:你用了集合
{"'sudo'", "cat", ...}作为参数,但subprocess.check_output要求的是字符串列表(或者设置shell=True时用单个命令字符串),而且'sudo'多了一层引号完全没必要。 - sudo权限问题:
/etc/shadow是root专属文件,sudo执行时需要交互式输入密码,但subprocess默认不会处理这种交互,直接导致命令执行失败退出。
解决方案
这里给你两种靠谱的方案,推荐第一种更安全可控:
方案一:配置sudo免密执行指定命令(推荐)
先让你的用户不用输入密码就能读取/etc/shadow,步骤如下:
- 打开sudoers配置文件(必须用
visudo,避免语法错误锁死系统):sudo visudo - 在文件末尾添加一行(把
your_username替换成你的实际用户名):your_username ALL=(ALL) NOPASSWD: /bin/cat /etc/shadow - 保存退出(vim按
Esc输入:wq回车)。
然后修改你的Python代码,用正确的subprocess写法,并且用Python自己处理awk的逻辑(比调用shell更灵活安全):
import subprocess # 用字符串列表传递命令参数,无需shell=True shadow_output = subprocess.check_output(["sudo", "cat", "/etc/shadow"]) # 解码字节流为字符串,逐行处理 for line in shadow_output.decode().splitlines(): # /etc/shadow的格式是 用户名:密码字段:其他信息... fields = line.split(":") if len(fields) >= 2: username = fields[0] pass_field = fields[1] # 空密码字段通常是''、'!!'(未设置密码)或'*'(锁定账户) if pass_field in ("", "!!", "*"): print(f"用户 {username} 的密码字段为空/未设置")
方案二:处理sudo交互式密码输入(不推荐,有安全风险)
如果你不想修改sudoers,可以用pexpect库处理密码输入,但直接写密码在代码里非常不安全,只适合测试环境:
- 先安装pexpect:
pip install pexpect - 修改代码:
import pexpect # 启动sudo命令,处理密码输入 process = pexpect.spawn("sudo cat /etc/shadow") # 匹配sudo的密码提示 process.expect("Password:") # 输入你的sudo密码(绝对不要在生产代码里这么写!) process.sendline("你的sudo密码") process.expect(pexpect.EOF) # 获取命令输出 shadow_content = process.before.decode() # 同样处理密码字段 for line in shadow_content.splitlines(): fields = line.split(":") if len(fields) >=2 and fields[1] in ("", "!!", "*"): print(f"用户 {fields[0]} 无密码")
总结
- 你遇到的exit status 1错误,部分由sudo导致(需要密码但无交互输入),但核心是subprocess参数格式错误;
- 优先用方案一,既安全又能避免交互问题;
- 永远不要在代码里硬编码sudo密码,这是严重的安全漏洞!
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

