由于实现不足,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。
为什么会这样:
Ansible在函数_symbolic_mode_to_octal
中包含了诸如: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中所提议的。
如果由于某种原因您不想使用“解决办法”并且需要一种类似于 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
不适用于文件。在第二种情况下,在设置了
u=x
之后,
X
将适用于文件,从而设置了
g=x
和
o=x
。