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
相关产品推荐
相关产品推荐

