You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本向/usr/local/bin写入文件遇权限拒绝,如何临时提权并恢复权限?

Python脚本写入/usr/local/bin权限报错解决方案

核心问题定位

报错根源完全来自目录所有者与执行用户的权限匹配差异,并非权限位显示的格式问题:

  • /usr/local/bin的原始权限为drwxr-xr-x,所有者是root:对非root用户、非root所属组的普通用户仅开放目录进入、只读权限,不允许新增、修改、删除目录内的文件,所以写入时触发IOError: [Errno 13] Permission denied
  • 你当前执行脚本的目录TermTime所有者是当前运行脚本的用户parallels,同样是drwxr-xr-x的权限位,作为目录所有者的你拥有完整的写入权限,所以同一份写入逻辑不会报错
  • 你观察到的“读取不报错、写入报错”的现象完全符合上述权限逻辑:755权限位对所有用户开放读权限,仅写入操作对非所有者用户有限制。

适配无编程基础用户的透明实现方案

整个流程除了需要用户输入一次系统登录密码外,无任何手动配置步骤,所有逻辑在脚本内部完成,对用户完全透明。

首选安全方案(无永久权限变更)

全程不主动修改/usr/local/bin的原始权限配置,通过系统原生sudo机制完成单次提权执行写入,从根源上避免权限被篡改带来的安全风险:

  • 普通用户运行脚本时,桌面系统会自动弹出标准的图形化密码输入框,用户输入自己的开机密码即可完成操作,无需在终端手动输入命令
  • 提权仅在脚本执行写入的阶段生效,脚本运行结束后自动退出高权限态,不会长期保留root权限

对应适配你原有测试逻辑的可直接运行代码:

import os
import sys
import subprocess
import datetime

def write_target_file():
    """ 实际写入逻辑,在提权环境下运行 """
    target_path = '/usr/local/bin/Test.txt'
    OUTFILE = open(target_path, 'w')
    today = datetime.date.today()
    todayStr = today.strftime('%Y-%m-%d')
    OUTFILE.write('{0}\n'.format(todayStr))
    OUTFILE.close()
    if os.path.isfile(target_path):
        print('Successfully wrote the file Test.txt.')
    else:
        print('Failed to write the Test.txt file.')

# 检测当前是否拥有root权限
if os.geteuid() != 0:
    # 非root态,自动调用sudo重新运行脚本本身
    subprocess.call(['sudo', sys.executable] + sys.argv)
else:
    # 已是root态,执行写入
    write_target_file()

可选实现(临时调整权限后恢复)

如果严格按照“临时修改目录权限、写入完成恢复原始状态”的需求实现,必须加入全链路异常捕获,保证哪怕脚本中途崩溃,也能把目录权限恢复到初始值,避免留下安全敞口。
核心执行流程:

  • 提权后首先读取/usr/local/bin的原始权限位、所有者ID、所属组ID,留存备份
  • 临时调整目录权限,允许当前进程写入目标文件
  • 执行文件写入操作
  • 通过finally代码块强制触发目录状态恢复,不受写入成功/失败、中途异常的影响

对应实现代码:

import os
import sys
import subprocess
import datetime
import stat

TARGET_DIR = '/usr/local/bin'
TARGET_FILE = os.path.join(TARGET_DIR, 'Test.txt')

if os.geteuid() != 0:
    subprocess.call(['sudo', sys.executable] + sys.argv)
else:
    # 留存目录原始状态
    origin_stat = os.stat(TARGET_DIR)
    try:
        # 临时放开目录的写入权限
        os.chmod(TARGET_DIR, origin_stat.st_mode | stat.S_IWOTH)
        # 执行写入
        OUTFILE = open(TARGET_FILE, 'w')
        today = datetime.date.today()
        todayStr = today.strftime('%Y-%m-%d')
        OUTFILE.write('{0}\n'.format(todayStr))
        OUTFILE.close()
        # 校验写入结果
        if os.path.isfile(TARGET_FILE):
            print('Successfully wrote the file Test.txt.')
        else:
            print('Failed to write the Test.txt file.')
    finally:
        # 无论执行结果如何,强制恢复目录的所有者、权限位
        os.chown(TARGET_DIR, origin_stat.st_uid, origin_stat.st_gid)
        os.chmod(TARGET_DIR, origin_stat.st_mode)

注意:这种临时调整权限的方式存在安全隐患——如果脚本在临时改权后、恢复权限前被强制终止,就会导致/usr/local/bin的权限被永久放开,所有普通用户都可以修改该目录下的系统可执行文件,存在被恶意利用提权的风险。无特殊需求优先选择第一种提权直接写入的方案。

常见误区澄清

  • 权限位显示格式一致不代表权限一致:drwxr-xr-x的实际生效权限和当前用户的身份强相关,所有者、所属组成员、其他用户对应的权限范围完全不同
  • 不要为了省事把/usr/local/bin的权限永久调整为777、或者把目录所有者改成普通用户:这类操作会破坏系统目录的安全规范,带来长期的安全风险

内容的提问来源于stack exchange,提问作者Barry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 19:06:04