【问题标题】:Does path.mkdir()'s updates the file permissions if path already exists and mode is passed?如果路径已存在且模式已通过,path.mkdir() 是否会更新文件权限?
【发布时间】:2020-05-18 23:03:45
【问题描述】:

我在 kubernetes 中附加了一个卷,路径为 /var/www/aaa/tmp

该卷是使用path.mkdir() 创建的,目前拥有755 权限。 它最初是使用代码 path.mkdir(parents=True, exist_ok=True) 创建的。

我正在尝试在不删除现有路径的情况下更新其权限。

我正在使用path.mkdir(parents=True, exist_ok=True, mode=0o777)。我仍然面临与权限相关的问题,并为创建上述目录的烧瓶应用程序获取502 Bad gateway

path.mkdir(parents=True, exist_ok=True, mode=0o777) 是否会更新路径权限(如果它已经存在并且具有755 权限)?还是会像我们提到的exists_ok=True 那样完全忽略它?我没有看到该路径的权限得到更新。

我是否应该完全删除路径并使用mode=0o777 重新运行path.mkdir..... 以创建新目录并设置权限?

编辑 1: 我试过在路径上使用os.chmod()。但它正在抛出PermissionError

这是代码 sn-p。

path.mkdir(parents=True, exist_ok=True)
os.chmod(path, mode=0o777)

错误:

文件“./app/init.py”,第 79 行,在 create_prediction_app 中 create_directories(app) 文件“./app/init.py”,第 36 行,在 create_directories os.chmod(path, mode=0o777) PermissionError: [Errno 1] Operation not allowed: '/var/www/aaa/tmp' 无法加载应用程序 0 (mountpoint='') (callable not found or import error) * no app 加载。游戏结束 *

【问题讨论】:

标签: python python-3.x chmod docker-volume 777


【解决方案1】:

如果路径已经存在,您应该使用os.chmod(path, mode) 而不是删除/重新创建。

例如:

import os

os.chmod("/var/www/aaa/tmp", 0o777)

此外,chmod 可以从stat 模块获得权限。

  • stat.S_ISUID - 在执行时设置用户 ID。
  • stat.S_ISGID - 在执行时设置组 ID。
  • stat.S_ENFMT - 强制记录锁定。
  • stat.S_ISVTX - 执行后保存文本图像。
  • stat.S_IREAD - 所有者阅读。
  • stat.S_IWRITE - 由所有者编写。
  • stat.S_IEXEC - 由所有者执行。
  • stat.S_IRWXU - 由所有者读取、写入和执行。
  • stat.S_IRUSR - 所有者读取。
  • stat.S_IWUSR - 由所有者编写。
  • stat.S_IXUSR - 由所有者执行。
  • stat.S_IRWXG - 按组读取、写入和执行。
  • stat.S_IRGRP - 按组读取。
  • stat.S_IWGRP - 按组写入。
  • stat.S_IXGRP - 按组执行。
  • stat.S_IRWXO - 由其他人读取、写入和执行。
  • stat.S_IROTH - 被其他人阅读。
  • stat.S_IWOTH - 由他人编写。
  • stat.S_IXOTH - 由其他人执行。

例如:

import os
import stat

# Set a file write by others.
os.chmod("/var/www/aaa/tmp", stat.S_IWOTH)

您可以使用按位运算符设置更多权限。

例如:

import os
import stat

os.chmod(
    '/var/www/aaa/tmp',
    stat.S_IRUSR |
    stat.S_IROTH |
    stat.S_IRGRP 
)

完成测试:

>>> touch test_perm.sh
>>> ll test_perm.sh
-rw-rw-r-- test_perm.sh
>>> python -c "import os; os.chmod('test_perm.sh', 0755)"
>>> ll test_perm.sh
-rwxr-xr-x test_perm.sh

编辑:

如果你想用os.chmod更改权限时遇到PermissionError: [Errno 1] Operation not permitted:...异常,你应该尝试下面的代码部分来解决它。以管理员权限运行脚本很重要(在 Linux 环境中使用 sudo)。

代码:

from getpwnam import pwd
from getgrnam import grp
import os

uid = getpwnam("USERNAME")[2]
gid = grp.getgrnam("GROUPNAME")[2]
os.chown("/var/www/aaa/tmp", uid, gid)

基于chown官方文档:

os.chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)

将路径的所有者和组 id 更改为数字 uid 和 gid。要保持其中一个 id 不变,请将其设置为 -1。

此函数可以支持指定文件描述符、相对于目录描述符的路径以及不遵循符号链接。

请参阅 shutil.chown() 以获取更高级别的函数,该函数除了接受数字 id 之外还接受名称。

可用性:Unix。

3.3 版中的新增功能:添加了对将路径指定为打开文件描述符以及 dir_fd 和 follow_symlinks 参数的支持。

3.6 版更改:支持类似路径的对象。

文档链接:https://docs.python.org/3/library/os.html#os.chown

【讨论】:

  • 您的第一个 sn-p 中有一个错误。它应该是0o777。此外,0755 将不再在 python3 中工作。 0o 是必填项。
  • 由于某种原因它授予755 权限,即使我提到了mode=0o777
  • 我已根据您的 PS 编辑了我的答案。我已经提到了解决PermissionError: [Errno 1] Operation not permitted:... 异常的可能解决方案。
【解决方案2】:

milanbalazs 的回答非常好,很好的解释,但只会 chmod 路径中的最后一个目录。在我的情况下,这还不够好,因为我需要确保每个子文件夹一直到最后一个也被 chmodded。

我找不到任何简单的方法来使用现有的 bash 工具来做到这一点,唯一接近我需要的工具是 chmod -R,但我也不想干预,除了特别指定的每个文件夹路径。

为了澄清,在示例中,我们有路径/var/www/aaa/tmp。我可能想从/var/www 开始,并确保/var/www/aaa/var/www/aaa/tmp 的权限设置为我想要的任何内容。

所以我写了下面的脚本来解决这个用例;

import os
import argparse

def base8(val):
    return int(val, base=8)

def path(val):
    assert os.path.exists(val)
    return val

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('start_dir', type=path, help='starting point for chmod to check for subdirectories')
    parser.add_argument('end_dir', help='last directory to be chmodded, relative to start_dir')
    parser.add_argument('permission', type=base8, help='permission to set on each directory (must be base 8 format e.g. "0o750")')

    args = parser.parse_args()
    return args

def main():
    args = parse_args()

    directories = os.path.split(args.end_dir)
    current_dir = args.start_dir
    for directory in directories:
        current_dir = os.path.join(current_dir, directory)
        os.chmod(current_dir, args.permission)

if __name__ == '__main__':
    main()

希望有一天有人会发现这很有用:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2018-10-25
    • 2010-10-03
    • 2016-08-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多