为了账号安全,请及时绑定邮箱和手机立即绑定

当`unlink`起作用时,为什么`rename`无法删除源文件

当`unlink`起作用时,为什么`rename`无法删除源文件

PHP
慕侠2389804 2022-07-29 09:40:05
我有一个 PHP 脚本使用 function 移动文件rename,但部分失败。调用rename会给出“权限被拒绝”警告。该文件似乎已经复制到目标目录(我在那里看到了它),但它仍然存在于.之后的源目录中rename。file_exists确认旧文件仍然存在。 unlink然后可以成功删除文件 - 它返回true并file_exists确认文件现在已经消失。该文件来自在 HTTP 请求中上传到/tmp目录中(我使用is_uploaded_file它来满足安全考虑 - 这不是这里的问题)。该文件确实具有rwWeb 服务用户 ( www-data) 的权限。move_uploaded_file也可以正常工作。目标目录位于已安装的 CIFS 目录中。Linux Ubuntu,PHP 版本 7.2.24。
查看完整描述

1 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

更新: OP 说目标目录是 CIFS 挂载。CIFS 挂载的权限可能更难理解 - 请参阅https://linux.die.net/man/8/mount.cifs部分“文件和目录所有权和权限” )

rename不是一个单一的原子动作(在 PHP 中)。它实际上调用(按正常文件的顺序):

  • copy(创建文件的新副本)

  • chown(设置新副本的所有权)

  • chmod(设置新副本的权限)

  • unlink(删除原文)

(源代码可在 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.

  */

我希望目标中父目录的权限(您要复制到的位置)阻止chmodorchown工作。


(注意:这不适用于 CIFS 挂载...请参阅答案顶部的链接。)作为一个超级丑陋的黑客,您可以尝试将目标目录的权限设置为777( chmod 777 /my/target/directory/),这是不好的做法,但会证明理论。


查看完整回答
反对 回复 2022-07-29
  • 1 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信