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

Linux下chmod()返回errno 13(权限拒绝)的问题求助

问题与排查方案

问题场景

尝试将新文件权限与旧文件保持一致,使用Qt5/C++编写的代码如下:

stat(oldFileName.toLatin1().data(), &sb);
bool success = chmod(newFileName.toLatin1().data(),sb.st_mode);

调用chmod()时,sb.st_mode值为十进制33261(对应八进制100755),但调用失败,errno被设为13(权限拒绝),且程序以uid 0、gid 0(root身份)运行。

后续更新:已注意到stat()返回的sb.st_mode高位包含文件类型信息,尝试用(sb.st_mode & 0x1FF)得到八进制0755作为chmod参数,仍然失败。

可能原因及解决方法

  • 文件系统不支持UNIX权限:如果新文件位于FAT32、exFAT这类不支持UNIX-style权限的文件系统上,即使root用户也无法修改权限。可通过df -T命令查看目标文件所在分区的文件系统类型,若为此类文件系统,需更换到支持权限的分区(如ext4)操作。
  • 目标是符号链接:chmod()默认修改符号链接指向的目标文件权限,而非链接本身。若要修改符号链接的权限,需改用lchmod()函数。
  • 安全模块限制:SELinux、AppArmor等系统安全模块可能会阻止root用户的权限修改操作。可临时关闭测试(如执行setenforce 0关闭SELinux),若操作恢复正常,需调整对应安全策略放行该操作。
  • 文件被锁定占用:如果新文件被其他进程锁定,会导致chmod()调用失败。用lsof命令可检查文件是否被其他进程占用,关闭占用进程后重试。
  • 字符串编码问题:toLatin1()在处理非ASCII文件名时可能出现编码错误,导致实际操作的文件路径不正确。建议改用toLocal8Bit()或toUtf8()(匹配系统编码),或者通过toStdString().c_str()获取C风格路径字符串。

调整后的示例代码:

struct stat sb;
if (stat(oldFileName.toLocal8Bit().data(), &sb) == 0) {
    mode_t perm = sb.st_mode & 0777; // 用八进制掩码提取权限位更直观
    int ret = chmod(newFileName.toLocal8Bit().data(), perm);
    if (ret != 0) {
        qDebug() << "chmod failed:" << strerror(errno);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:35:06