为什么 `rename` 无法删除源文件,而 `unlink` 有效
Why does `rename` fail to delete the source file, when `unlink` works
我有一个 PHP 脚本使用函数 rename
移动文件,但部分失败了。调用 rename
会给出 "Permission denied" 警告。该文件似乎已被复制到目标目录(我在那里看到它很好),但它仍然存在于 rename
.
之后的源目录中
file_exists
确认旧文件仍然存在。
unlink
然后可以成功删除文件 – 它 returns true
和 file_exists
确认文件现在已经消失了。
文件来自在 HTTP 请求中上传到 /tmp
目录(我使用 is_uploaded_file
来满足安全考虑——这不是这里的问题)。该文件确实具有 Web 服务用户 (www-data
) 的 rw
权限。 move_uploaded_file
也可以正常工作。
目标目录在挂载的 CIFS 目录中。
Linux Ubuntu, PHP 版本 7.2.24.
(更新: OP 说目标目录是 CIFS 挂载。CIFS 挂载的权限可能更难以理解 - 请参阅 https://linux.die.net/man/8/mount.cifs 部分“文件和目录的所有权和权限")
rename
不是单个原子操作(在 PHP 中)。它实际上调用(对于普通文件按此顺序):
copy
(创建文件的新副本)
chown
(设置新副本的归属)
chmod
(设置新副本的权限)
unlink
(删去原来的)
(源代码为available on GitHub。)
如果这些步骤中的任何一个失败,它会中止并显示错误代码,并且不会回滚(这与您看到的症状一致)。
旁注:这实际上在源代码中记录为可能的行为:
/*
* Try to set user and permission info on the target.
* If we're not root, then some of these may fail.
* We try chown first, to set proper group info, relying
* on the system environment to have proper umask to not allow
* access to the file in the meantime.
*/
我希望 目标 中父目录的权限(您正在将 复制到 的位置)阻止了 chmod
或 chown
从工作。
(NB: 这不适用于 CIFS 安装...请参阅答案顶部的 link。)作为一个超级丑陋的 hack,你可以尝试将目标目录的权限设置为 777
(chmod 777 /my/target/directory/
),这是不好的做法,但会证明理论。
我有一个 PHP 脚本使用函数 rename
移动文件,但部分失败了。调用 rename
会给出 "Permission denied" 警告。该文件似乎已被复制到目标目录(我在那里看到它很好),但它仍然存在于 rename
.
file_exists
确认旧文件仍然存在。
unlink
然后可以成功删除文件 – 它 returns true
和 file_exists
确认文件现在已经消失了。
文件来自在 HTTP 请求中上传到 /tmp
目录(我使用 is_uploaded_file
来满足安全考虑——这不是这里的问题)。该文件确实具有 Web 服务用户 (www-data
) 的 rw
权限。 move_uploaded_file
也可以正常工作。
目标目录在挂载的 CIFS 目录中。
Linux Ubuntu, PHP 版本 7.2.24.
(更新: OP 说目标目录是 CIFS 挂载。CIFS 挂载的权限可能更难以理解 - 请参阅 https://linux.die.net/man/8/mount.cifs 部分“文件和目录的所有权和权限")
rename
不是单个原子操作(在 PHP 中)。它实际上调用(对于普通文件按此顺序):
copy
(创建文件的新副本)chown
(设置新副本的归属)chmod
(设置新副本的权限)unlink
(删去原来的)
(源代码为available on GitHub。)
如果这些步骤中的任何一个失败,它会中止并显示错误代码,并且不会回滚(这与您看到的症状一致)。
旁注:这实际上在源代码中记录为可能的行为:
/* * Try to set user and permission info on the target. * If we're not root, then some of these may fail. * We try chown first, to set proper group info, relying * on the system environment to have proper umask to not allow * access to the file in the meantime. */
我希望 目标 中父目录的权限(您正在将 复制到 的位置)阻止了 chmod
或 chown
从工作。
(NB: 这不适用于 CIFS 安装...请参阅答案顶部的 link。)作为一个超级丑陋的 hack,你可以尝试将目标目录的权限设置为 777
(chmod 777 /my/target/directory/
),这是不好的做法,但会证明理论。