Ansible - 模式755用于目录,644用于文件递归

时间:2015-02-28 06:05:08

标签: file-permissions ansible

我想允许任何人列出并阅读目录树中的所有文件,但我不想让文件可执行:

dir
  \subdir1
      file1
  \subdir2
      file2
  ...
  \subdirX
      fileX

以下任务使我的目录和文件可读,但它也使所有文件都可执行:

- name: Make my directory tree readable
  file:
    path: dir
    mode: 0755
    recurse: yes

另一方面,如果我选择模式0644,那么我的所有文件都不可执行,但我无法列出我的目录。

是否可以为所有目录设置模式755,为目录树中的所有文件设置644?

谢谢。

4 个答案:

答案 0 :(得分:91)

从1.8版开始,Ansible支持符号模式。因此,以下将执行您想要的任务:

- name: Make my directory tree readable
  file:
    path: dir
    mode: u=rwX,g=rX,o=rX
    recurse: yes

因为X(而不是x)仅适用于至少设置了x位的目录或文件。

答案 1 :(得分:24)

Ansible文件/副本模块没有为您提供基于文件类型指定权限的粒度,因此您很可能需要通过以下方式执行此操作来手动执行此操作:

- name: Ensure directories are 0755
  command: find {{ path }} -type d -exec chmod -c 0755 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""

- name: Ensure files are 0644
  command: find {{ path }} -type f -exec chmod -c 0644 {} \;
  register: chmod_result
  changed_when: "chmod_result.stdout != \"\""

这些会产生递归{{ path }}并将每个文件或目录的权限更改为指定权限的效果。

答案 2 :(得分:3)

由于实现方式“不适当”,Ansible仅部分支持符号模式(请参见下面的说明)。

除了使用命令行chmod以外,使用Ansible将模式设置为u=rwX,g=rX,o=rX仍然不足以将文件设置为644。 产生的权限也将取决于文件的原始模式!

chmod的文档中所述,并且已经通过一些评论指出了该问题的其他答案: 如果ugo的文件权限是可执行的,则X还将文件权限设置为x

例如。如果一个文件的模式为740 -rwxr-----,将模式u=rwX,g=rX,o=rX设置为ansible,则会得到755 -rwxr-xr-x而不是预期的644 -rw-r--r--。 尽管这不是您想要的,但是它将使该文件可以按组和其他出现不需要的安全问题的人执行。

在这种情况下,使用Ansible,您将需要两个步骤来将文件权限设置为644。

- file:
    path: /path/to/dir
    state: directory
    recurse: yes
    mode: '{{ item }}'
  loop:
    - '-x'
    - 'u=rwX,g=rX,o=rX'
  • 请注意,如果您想为文件使用模式744,则需要u=rwx,g=rX,o=rX(第一个x小写!)。对于当前的实现 BUT ,这将在Ansible中工作,这不是命令行chmod的工作方式。请参见下面的**具有chmod的符号节点。

为什么会这样:

函数_symbolic_mode_to_octal中的Ansible状态包括以下内容:u=rw-x+X,g=r-x+X,o=r-x+X。 但是,如果给定模式为g=-x+X,则ansible会忽略-x烫发。 函数_symbolic_mode_to_octal遍历给定的权限, 当涉及到X时,函数_get_octal_mode_from_symbolic_perms不会将请求的权限与已应用的权限进行比较,而是与原始权限进行比较,从而将其忽略:

这可能是Ansible中的错误。

最简单有效的方法是委托给shell命令:如@BruceP's answer中所建议。

如果由于某种原因您不愿意使用“替代方法”,并且需要一种简单的方法来解决问题,您并不关心性能,则可以尝试以下操作:

注意:这将花费非常长的时间,具体取决于文件和目录的数量!

- name: example
  hosts: 192.168.111.123
  become: yes
  gather_facts: no
  vars:
    path_to_dir: /path/to/dir
    target_mode_for_directories: 755
    target_mode_for_files: 644
  tasks:
    - name: collect list of directories '{{ path_to_dir }}'
      find:
        paths: '{{ path_to_dir }}'
        recurse: yes
        file_type: directory
      register: found_directories
    - name: set collected directories to mode '{{ target_mode_for_directories }}'
      file:
        dest: '{{ item.path }}'
        mode: '{{ target_mode_for_directories }}'
      loop: '{{ found_directories.files }}'
    - name: collect list of files under '{{ path_to_dir }}'
      find:
        paths: '{{ path_to_dir }}'
        recurse: yes
        file_type: file
      register: found_files
    - name: set collected files to mode '{{ target_mode_for_files }}'
      file:
        dest: '{{ item.path }}'
        mode: '{{ target_mode_for_files }}'
      loop: '{{ found_files.files }}'

使用chmod的符号模式

请记住,使用chmod设置符号模式可能非常棘手。 请参见以下示例,它们只是在小写和大写X的顺序上有所不同,即u=X,g=X,o=x(o =小写字母x)与u=x,g=X,o=X(u =小写字母x)导致{{ 1}}与001 ---------x

111 ---x--x--x

这是由于以下事实:首先为$ sudo chmod -R 000 path/to/file; \ sudo chmod -R u=X,g=X,o=x path/to/file; \ sudo find path/to/file -printf ""%03m" "%M" "%p\\n""; 001 ---------x path/to/file $ sudo chmod -R 000 path/to/file; \ sudo chmod -R u=x,g=X,o=X path/to/file; \ sudo find path/to/file -printf ""%03m" "%M" "%p\\n""; 111 ---x--x--x path/to/file 处理烫发,然后为u处理烫发,最后为g处理烫发。在第一个示例中,o不会申请文件,因为没有X烫发。在第二种情况下,x将在设置X之后应用于文件,因此同时设置了u=xg=x

答案 3 :(得分:1)

这对我有用:

- file:
    path: dir
    mode: a-x
    recurse: yes
- file:
    path: dir
    mode: u=rwX,g=rX,o=rX
    recurse: yes

首先从所有权限中删除执行权限,否则,group和其他人将获得文件的执行权限。

请参阅chmod有关X指令的手册页:

仅在文件是目录或已经执行时执行/搜索 某些用户(X)的权限

这也可行:

- shell: "chmod -R a-x,u=rwX,g=rX,o=rX dir"

由于某些原因,这两种组合无法使用:

- file:
    path: dir
    mode: a-x,u=rwX,g=rX,o=rX
    recurse: yes