如何用Python向root权限保护文件写入内容?subprocess调用报错
解决Python中通过sudo写入root权限文件的问题
我来帮你排查下这两个代码片段的问题,再给出更可靠的解决方案:
问题分析
第一个代码的错误原因
你把shell命令拆成了列表形式传给subprocess.call,同时设置了shell=True——这会导致命令解析混乱。当shell=True时,如果传入列表,第一个元素会被当作要执行的命令,后面的元素会被当作该命令的参数,但你这里把"echo、link、>>/root/.config/notify-run"拆成了三个元素,shell无法正确解析未闭合的引号,所以报错syntax error unterminated quoted string。
第二个代码的错误原因
管道|是shell的专属功能,当你用列表形式传命令且shell=True时,subprocess不会把|当作管道处理,而是把|、sudo、tee...都当作echo的参数。实际上执行的是把所有内容输出到控制台,根本没有触发管道写入文件的操作,所以目标文件不会有内容。
可行解决方案
方案1:修正shell=True的写法(字符串形式传命令)
如果一定要用shell模式,需要把整个命令作为单个字符串传递,同时注意对link进行转义,避免特殊字符导致的语法错误:
import subprocess import shlex link = 'the endpoint' # 转义link中的特殊字符,防止shell注入和语法错误 escaped_link = shlex.quote(link) # 用字符串形式传递完整命令 command = f'sudo sh -c "echo {escaped_link} >> /root/.config/notify-run"' subprocess.call(command, shell=True)
或者用管道的写法:
import subprocess import shlex link = 'the endpoint' escaped_link = shlex.quote(link) command = f'echo {escaped_link} | sudo tee -a /root/.config/notify-run' subprocess.call(command, shell=True)
方案2:更安全的无shell模式(推荐)
shell=True存在shell注入的安全风险,尤其是当link来自外部输入时。更可靠的方式是直接调用sudo tee,通过subprocess的input参数传递内容:
import subprocess link = 'the endpoint' # 调用sudo tee追加内容,input传递字节形式的link try: subprocess.run( ['sudo', 'tee', '-a', '/root/.config/notify-run'], input=link.encode('utf-8'), check=True, stdout=subprocess.DEVNULL # 屏蔽tee的输出到控制台,可选 ) print("内容写入成功") except subprocess.CalledProcessError: print("写入失败,请检查sudo权限")
这个方法不需要依赖shell,避免了引号和管道的解析问题,同时更安全。如果需要查看tee的输出,可以去掉stdout=subprocess.DEVNULL参数。
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

