Anble-目录模式为755,文件模式为644

我希望允许任何人列出并读取我的目录树中的所有文件,但我不想让这些文件成为可执行文件:

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

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

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

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

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

64836 次浏览

可视化文件/复制模块没有给出基于文件类型指定权限的粒度,因此您很可能需要手动执行以下操作:

- 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 }}并将每个文件或目录的权限更改为指定的权限。

从1.8版本开始,安赛尔就支持符号模式。因此,下面的代码可以完成你想要的任务:

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

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

这对我很有效:

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

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

请参阅 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

由于“不充分”的实现,Anble 只支持部分符号模式(参见下面的解释)。

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

正如 chmod的文件所述,并且在对这个问题的其他答复的一些评论中已经指出: 如果 ugo的文件权限是可执行的,那么 X将把该文件权限也设置为 x

比如说。如果一个文件有模式740-rwxr-----,设置模式 u=rwX,g=rX,o=rX与可见,您将得到755-rwxr-xr-x而不是预期的644-rw-r--r--。 尽管这不是您想要的,但是它将使文件可以按组和其他存在不必要安全问题的组执行。

在这些情况下,您将需要两个步骤来设置文件的权限为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小写!).这将工作在 Ansible,因为目前的实现 abc3这不是命令行 abc2的工作方式。请参见下面带 * chmod 的 * * 符号节点。

为什么会这样:

函数 _symbolic_mode_to_octal中的可见状态包括以下内容: u=rw-x+X,g=r-x+X,o=r-x+X。 尽管如此,如果给定的模式是 g=-x+X,可以忽略 -x perm。 函数 _symbolic_mode_to_octal迭代给定的权限, 当涉及到 X时,函数 _get_octal_mode_from_symbolic_perms不会将请求的权限与已经应用的权限进行比较,而是与原始权限进行比较,因此忽略了它:

这可能是 Ansible 的一个窃听器。

最简单有效的方法是委托给 shell 命令: 如 @ Bruce 的回答中所建议的。

如果出于某种原因,你反对使用“变通方法”,并且需要一种可行的方法来解决问题 你根本不在乎表现,你可以尝试以下方法:

注意: 根据文件和目录的数量,这将花费非常、非常长的时间!

- 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) ,这导致了 001 ---------x111 ---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 perm。在第二种情况下,X将在设置 u=x之后申请文件,从而同时设置 g=xo=x