Ansible - 目录模式 755 和文件模式 644 递归
Ansible - Mode 755 for directories and 644 for files recursively
我想允许任何人列出和读取我的目录树中的所有文件,但我不想让这些文件可执行:
dir
\subdir1
file1
\subdir2
file2
...
\subdirX
fileX
以下任务使我的目录和文件可读,但它也使所有文件可执行:
- name: Make my directory tree readable
file:
path: dir
mode: 0755
recurse: yes
另一方面,如果我选择模式 0644,那么我的所有文件都不可执行,但我无法列出我的目录。
是否可以为目录树中的所有目录设置模式 755,为所有文件设置模式 644?
Ansible file/copy 模块不会为您提供根据文件类型指定权限的粒度,因此您很可能需要通过以下方式手动执行此操作:
- 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 版本开始,Ansible 支持符号模式。因此,以下将执行您想要的任务:
- 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 指令的手册页:
execute/search only if the file is a directory or already has execute
permission for some user (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
由于 "inadequate" 实现,Ansible 仅部分支持符号模式(参见下面的解释)。
除了使用命令行 chmod
之外,使用 Ansible 将模式设置为 u=rwX,g=rX,o=rX
并不总是足以让您的文件设置为 644。
产生的权限也将取决于文件的原始模式!
正如 chmod
的文档中所述,一些评论已经指出了这个问题的其他答案:
如果 u
、g
或 o
的文件权限是可执行的,则 X
也会将文件权限设置为 x
。
例如。如果一个文件的模式为 740 -rwxr-----
,使用 ansible 设置模式 u=rwX,g=rX,o=rX
,您将得到 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
小写!)。对于当前的实现,这将在 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
perm。
函数 _symbolic_mode_to_octal
遍历给定的权限,
当涉及到 X
时,函数 _get_octal_mode_from_symbolic_perms
不会将请求的权限与已经应用的权限进行比较,而是与原始权限进行比较,因此忽略它:
这可能是 Ansible 中的一个错误。
最简单有效的方法是委托给 shell 命令:如 中所建议的那样。
如果出于某种原因你不喜欢使用 'workarounds' 并且需要一种类似 ansible 的方法来解决问题 并且你不关心性能 你可以尝试以下操作:
注意:这将花费非常非常长的时间,具体取决于文件和目录的数量!
- 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 ---------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
perm。在第二种情况下,X
将在设置了u=x
之后申请文件,因此同时设置了g=x
和o=x
我想允许任何人列出和读取我的目录树中的所有文件,但我不想让这些文件可执行:
dir
\subdir1
file1
\subdir2
file2
...
\subdirX
fileX
以下任务使我的目录和文件可读,但它也使所有文件可执行:
- name: Make my directory tree readable
file:
path: dir
mode: 0755
recurse: yes
另一方面,如果我选择模式 0644,那么我的所有文件都不可执行,但我无法列出我的目录。
是否可以为目录树中的所有目录设置模式 755,为所有文件设置模式 644?
Ansible file/copy 模块不会为您提供根据文件类型指定权限的粒度,因此您很可能需要通过以下方式手动执行此操作:
- 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 版本开始,Ansible 支持符号模式。因此,以下将执行您想要的任务:
- 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 指令的手册页:
execute/search only if the file is a directory or already has execute permission for some user (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
由于 "inadequate" 实现,Ansible 仅部分支持符号模式(参见下面的解释)。
除了使用命令行 chmod
之外,使用 Ansible 将模式设置为 u=rwX,g=rX,o=rX
并不总是足以让您的文件设置为 644。
产生的权限也将取决于文件的原始模式!
正如 chmod
的文档中所述,一些评论已经指出了这个问题的其他答案:
如果 u
、g
或 o
的文件权限是可执行的,则 X
也会将文件权限设置为 x
。
例如。如果一个文件的模式为 740 -rwxr-----
,使用 ansible 设置模式 u=rwX,g=rX,o=rX
,您将得到 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
小写!)。对于当前的实现,这将在 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
perm。
函数 _symbolic_mode_to_octal
遍历给定的权限,
当涉及到 X
时,函数 _get_octal_mode_from_symbolic_perms
不会将请求的权限与已经应用的权限进行比较,而是与原始权限进行比较,因此忽略它:
这可能是 Ansible 中的一个错误。
最简单有效的方法是委托给 shell 命令:如
如果出于某种原因你不喜欢使用 'workarounds' 并且需要一种类似 ansible 的方法来解决问题 并且你不关心性能 你可以尝试以下操作:
注意:这将花费非常非常长的时间,具体取决于文件和目录的数量!
- 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 ---------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
perm。在第二种情况下,X
将在设置了u=x
之后申请文件,因此同时设置了g=x
和o=x