* copy模块

copy模块用于将本地或远程机器上的文件拷贝到远程主机上。

模块参数

名称 必选 默认值 可选值 备注
backup no no yes/no 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,可选值有yes和no,当设置为yes时,会先备份远程主机中的文件,然后再将ansible主机中的文件拷贝到远程主机。
content no 当用content代替src参数的时候,可以把文档的内容设置到特定的值,src与content两个参数必有其一
dest yes 目标绝对路径。如果src是一个目录,dest也必须是一个目录。如果dest是不存在的路径,并且如果dest以/结尾或者src是目录,则dest被创建。如果src和dest是文件,如果dest的父目录不存在,任务将失败
follow no no yes/no 是否遵循目的机器中的文件系统链接
force no yes yes/no 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否强制覆盖。设置为no,则只有在目标不存在的情况下才会传输文件
group no 指定文件拷贝到远程主机后的属组,将被馈送到chown,远程主机上必须有对应的组
local_follow no yes yes/no 是否遵循本地机器中的文件系统链接
mode no 指定文件拷贝到远程主机后的权限,模式实际上是八进制数字(如0644),少了前面的零可能会有意想不到的结果。从版本1.8开始,可以将模式指定为符号模式(例如u+rwx或u=rw,g=r,o=r)
owner no 指定文件拷贝到远程主机后的属主,将被馈送到chown,远程主机上必须有对应的用户,想要在user对应的权限位上添加执行权限,则可以使用mode=u+x表示。
remote_src(2.0+) no no yes/no 如果yes它会从目标机上搜索src文件
src no 将本地路径复制到远程服务器; 可以是绝对路径或相对的。如果是一个目录,它将被递归地复制。如果路径以/结尾,则只有该目录下内容被复制到目的地,如果没有使用/来结尾,则包含目录在内的整个内容全部复制
unsafe_writes no yes/no 是否以不安全的方式进行,可能导致数据损坏
validate no None 复制前是否检验需要复制目的地的路径
Directory_mode no 设定目录的权限,只有在新建的时候才会使用,不会影响已经存在的目录

拷贝文件

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0

[root@Super ~]# ansible A -R root -S -m copy -a "src=/app/download/discovertcpport.sh dest=/app/ansible/"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "checksum": "28641daa8d54e87e2bda20f9323038ff65def337", 
    "dest": "/app/ansible/discovertcpport.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "08a92fee20a9416350b8ad00b2951039", 
    "mode": "0664", 
    "owner": "root", 
    "size": 747, 
    "src": "/home/ywbz/.ansible/tmp/ansible-tmp-1529920379.0-181601513039168/source", 
    "state": "file", 
    "uid": 0
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rw-rw-r-- 1 root root 747 Jun 25 17:52 discovertcpport.sh

[root@Super ~]# 

src可以是文件,也可以是目录,如果是一个目录,它将被递归地复制。如果路径以/结尾,则只有该目录下内容被复制到目的地,如果没有使用/来结尾,则包含目录在内的整个内容全部复制
如果src是一个目录,dest也必须是一个目录。如果dest是不存在的路径,并且如果dest以/结尾或者src是目录,则dest被创建。如果src和dest是文件,如果dest的父目录不存在,任务将失败

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rw-rw-r-- 1 root root 747 Jun 25 17:52 discovertcpport.sh

[root@Super ~]# ansible A -R root -S -m copy -a "src=/app/download dest=/app/ansible/"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "dest": "/app/ansible/", 
    "src": "/app/download"
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rw-rw-r-- 1 root root 747 Jun 25 17:52 discovertcpport.sh
drwxrwxr-x 2 root root 105 Jun 25 17:57 download

[root@Super ~]# ansible A -R root -S -m copy -a "src=/app/download/ dest=/app/ansible/"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "dest": "/app/ansible/", 
    "src": "/app/download/"
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 44
-rw-rw-r-- 1 root root   747 Jun 25 17:52 discovertcpport.sh
drwxrwxr-x 2 root root   105 Jun 25 17:57 download
-rw-rw-r-- 1 root root 17133 Jun 25 18:02 Initialization_HuaWei.sh
-rw-rw-r-- 1 root root 17148 Jun 25 18:02 Install-Monitor_Initialization.sh

[root@Super ~]#

拷贝备份

当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,可选值有yes和no,当设置为yes时,会先备份远程主机中的文件,然后再将ansible主机中的文件拷贝到远程主机,备份的文件在同级目录下,文件名带时间戳

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rw-rw-r-- 1 root root 748 Jun 25 18:13 discovertcpport.sh

[root@Super ~]# ansible A -R root -S -m copy -a "src=/app/download/discovertcpport.sh dest=/app/ansible/ backup=yes"
10.15.43.13 | SUCCESS => {
    "backup_file": "/app/ansible/discovertcpport.sh.63267.2018-06-25@18:13:50~", 
    "changed": true, 
    "checksum": "28641daa8d54e87e2bda20f9323038ff65def337", 
    "dest": "/app/ansible/discovertcpport.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "08a92fee20a9416350b8ad00b2951039", 
    "mode": "0664", 
    "owner": "root", 
    "size": 747, 
    "src": "/home/ywbz/.ansible/tmp/ansible-tmp-1529921629.06-221684734855733/source", 
    "state": "file", 
    "uid": 0
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 8
-rw-rw-r-- 1 root root 747 Jun 25 18:13 discovertcpport.sh
-rw-rw-r-- 1 root root 748 Jun 25 18:13 discovertcpport.sh.63267.2018-06-25@18:13:50~

[root@Super ~]#

创建文件

[root@Super ~]# ansible A -R root -S -m copy -a 'content="justin\n51cto" dest=/app/ansible/test.txt owner=justin group=justin mode=0755'
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "checksum": "c10bf116f93052871549887aa7770c3bf96f42da", 
    "dest": "/app/ansible/test.txt", 
    "gid": 1003, 
    "group": "justin", 
    "md5sum": "491b495055a6a9ed163af1b31d9bfe0b", 
    "mode": "0755", 
    "owner": "justin", 
    "size": 12, 
    "src": "/home/ywbz/.ansible/tmp/ansible-tmp-1529923571.46-175093825189730/source", 
    "state": "file", 
    "uid": 1003
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rwxr-xr-x 1 justin justin 12 Jun 25 18:46 test.txt

[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test.txt"
10.15.43.13 | SUCCESS | rc=0 >>
justin
51cto

[root@Super ~]# 

使用content指定文件内容时,dest参数对应的值必须是一个文件,而不能是一个路径。

* file模块

file模块可以帮助我们完成一些对文件的基本操作,比如创建文件或目录、创建链接文件、删除文件或目录、修改文件权限等。

模块参数

参数 必填 默认 选项 说明
Follow NO no yes/no 这个标识说明这是系统链接文件,如果存在,应该遵循
path yes 必须参数,用于指定要操作的文件或目录,在之前版本的ansible中,使用dest参数或者name参数指定要操作的文件或目录,为了兼容之前的版本,使用dest或name也可以。
force no no yes/no 当state=link,force=yes时,表示强制创建链接文件,强制创建链接文件有以下几种情况:一:当创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。二:当创建链接文件的目录中已经存在与链接文件同名的文件时,会将同名文件覆盖为链接文件,相当于删除同名文件,创建链接文件。三:当创建链接文件的目录中已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制替换同名文件为链接文件。
group no 用于指定被操作文件的属组,属组对应的组必须在远程主机中存在,否则会报错。
owner no 用于指定被操作文件的属主,属主对应的用户必须在远程主机中存在,否则会报错。
mode no 用于指定被操作文件的权限,如将文件权限设置为"rw-r-x---",可以使用mode=650,或ode=0650,如设置特殊权限,如suid,可以使用mode=4700。
recurse no no yes/no 递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest 被链接到的路径,只应用于state=link的情况
state no file File/link Directory Hard/touch Absent 状态,有以下选项:directory:如果目录不存在,就创建目录touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间file:即使文件不存在,也不会被创建link:创建软链接hard:创建硬链接absent:删除目录、文件或者取消链接文件
src no 当state设置为link或者hard时,必须指明软链或硬链链接的哪个文件,通过src参数即可指定链接源

删除文件

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 4
-rwxr-xr-x 1 justin justin 12 Jun 25 18:46 test.txt

[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/test.txt state=absent"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "path": "/app/ansible/test.txt", 
    "state": "absent"
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0

[root@Super ~]# 

创建文件、目录

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0

[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/test state=touch"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "dest": "/app/ansible/test", 
    "gid": 0, 
    "group": "root", 
    "mode": "0664", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
-rw-rw-r-- 1 root root 0 Jun 25 20:52 test

[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/test state=touch"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "dest": "/app/ansible/test", 
    "gid": 0, 
    "group": "root", 
    "mode": "0664", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
-rw-rw-r-- 1 root root 0 Jun 25 20:53 test

[root@Super ~]#

state=touch,如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间

[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/test state=directory force=yes"
10.15.43.13 | FAILED! => {
    "changed": false, 
    "gid": 0, 
    "group": "root", 
    "mode": "0664", 
    "msg": "/app/ansible/test already exists as a file", 
    "owner": "root", 
    "path": "/app/ansible/test", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@Super ~]#

创建目录时,名字不能和当前目录下文件同名

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
drwxrwxr-x 2 root root 6 Jun 25 20:57 dir
-rw-rw-r-- 1 root root 0 Jun 25 20:53 test
[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/dir state=directory force=yes owner=justin group=51cto recurse=yes"
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "gid": 1004, 
    "group": "51cto", 
    "mode": "0775", 
    "owner": "justin", 
    "path": "/app/ansible/dir", 
    "size": 6, 
    "state": "directory", 
    "uid": 1003
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
drwxrwxr-x 2 justin 51cto 6 Jun 25 21:11 dir
-rw-rw-r-- 1 root   root  0 Jun 25 20:53 test

[root@Super ~]# 

创建软连接

[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
drwxrwxr-x 2 root root 6 Jun 25 20:57 dir
-rw-rw-r-- 1 root root 0 Jun 25 20:53 test

[root@Super ~]# ansible A -R root -S -m file -a "path=/app/ansible/logs state=link src=/var/log/messages-`date +"%Y%m%d"` force=yes"
 [WARNING]: Cannot set fs attributes on a non-existent symlink target. follow should be set to False to avoid this.

10.15.43.13 | SUCCESS => {
    "changed": true, 
    "dest": "/app/ansible/logs", 
    "src": "/var/log/messages-20180625", 
    "state": "absent"
}
[root@Super ~]# ansible A -R root -S -m shell -a "ls -l /app/ansible"
10.15.43.13 | SUCCESS | rc=0 >>
total 0
drwxrwxr-x 2 root root  6 Jun 25 20:57 dir
lrwxrwxrwx 1 root root 26 Jun 25 21:06 logs -> /var/log/messages-20180625
-rw-rw-r-- 1 root root  0 Jun 25 20:53 test

[root@Super ~]# 

* fetch

主要是将远程主机中的文件拷贝到本机中,和copy模块的作用刚刚相反,并且在保存的时候使用hostname来进行保存,当文件不存在的时候,会出现错误,除非设置了选项fail_on_missing为yes

  • 主要参数:
参数 必填 默认值 选项 说明
Dest yes 用来存放文件的目录,例如存放目录为backup,源文件名称为/etc/profile在主机pythonserver中,那么保存为/backup/pythonserver/etc/profile
Fail_on_missing NO NO yes/no 当源文件不存在的时候,标识为失败
Flat NO 允许覆盖,默认行为从hostname/path到/file的,如果dest以/结尾,它将使用源文件的基础名称
Src YES 在远程拉取的文件,并且必须是一个file,不能是目录
Validate_checksum no yes yes/no 当文件fetch之后进行md5检查
  • fetch一个文件进行保存
    【Absible学习】Ansible常用模块---文件操作_第1张图片
[root@Super ansible]# ansible 10.15.97.136 -m fetch -a 'src=/app/redis/etc/redis_6979.conf dest=/app/soft'
10.15.97.136 | SUCCESS => {
    "changed": true, 
    "checksum": "f64ceda6e7345a7b1c77fc8633d5ffa08e03605e", 
    "dest": "/app/soft/10.15.97.136/app/redis/etc/redis_6979.conf", 
    "md5sum": "4bba6ceed723e554a4553aebf77f9735", 
    "remote_checksum": "f64ceda6e7345a7b1c77fc8633d5ffa08e03605e", 
    "remote_md5sum": null
}
[root@Super ansible]#

src表示为远程主机上需要传送的文件路径,dest表示为本机上的路径,在传送过来的文件,是按照IP地址进行分类,然后路径是源文件的路径,在拉取文件的时候,必须拉取的是文件,不能拉取文件夹。

  • 指定路径目录进行保存

【Absible学习】Ansible常用模块---文件操作_第2张图片

[root@Super ansible]# ansible 10.15.97.136 -m fetch -a 'src=/app/redis/etc/redis_6979.conf dest=/app/soft/ flat=yes'
10.15.97.136 | SUCCESS => {
    "changed": true, 
    "checksum": "f64ceda6e7345a7b1c77fc8633d5ffa08e03605e", 
    "dest": "/app/soft/redis_6979.conf", 
    "md5sum": "4bba6ceed723e554a4553aebf77f9735", 
    "remote_checksum": "f64ceda6e7345a7b1c77fc8633d5ffa08e03605e", 
    "remote_md5sum": null
}
[root@Super ansible]# ls /app/soft
redis_6979.conf
[root@Super ansible]# 

在使用参数为flat的时候,如果dest的后缀名为/,那么就会保存在目录中,然后直接保存为文件名;当dest后缀不为/的时候,那么就会直接保存为kel的文件。

* blockinfile模块

blockinfile模块可以在指定的文件中插入"一段文本",对文本做标记,以便在以后的操作中可以通过"标记"找到这段文本,然后修改或者删除它。

常用参数

参数 说明
path 必须参数,指定要操作的文件。
block 此参数用于指定想要操作的那"一段文本",此参数有一个别名叫"content",使用content或block的作用是相同的。
marker 假如在指定文件中插入一段文本,ansible会自动为这段文本添加两个标记,一个开始标记,一个结束标记,默认情况下,开始标记为# BEGIN ANSIBLE MANAGED BLOCK,结束标记为# END ANSIBLE MANAGED BLOCK,使用marker参数自定义"标记",比如,marker=#{mark}test ,开始标记变为# BEGIN test,结束标记变为# END test,{mark}会自动被替换成开始标记和结束标记中的BEGIN和END,也可以插入很多段文本,为不同的段落添加不同的标记,下次通过对应的标记即可找到对应的段落。
state 可选值present与absent,默认情况下,将指定的一段文本"插入"到文件中,如果对应的文件中已经存在对应标记的文本,默认会更新对应段落,在执行插入操作或更新操作时,state的值为present,默认值就是present,如果对应的文件中已经存在对应标记的文本并且将state的值设置为absent,则表示从文件中删除对应标记的段落。
insertafter 在插入一段文本时,默认会在文件的末尾插入文本,如果将文本插入在某一行的后面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则)将文本插入在符合正则表达式的行的后面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为EOF,EOF表示End Of File,表示将文本插入到文档末尾。
insertbefore 在插入一段文本时,默认会在文件的末尾插入文本,如果要将文本插入在某一行的前面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则)将文本插入在符合正则表达式的行的前面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为BOF,BOF表示Begin Of File,表示将文本插入到文档开头。
backup 是否在修改文件之前对文件进行备份。
create 当要操作的文件并不存在时,是否创建对应的文件。

创建标记

[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test"
10.15.43.13 | SUCCESS | rc=0 >>
1
22
333

[root@Super ~]# ansible A -R root -S -m blockinfile -a 'path=/app/ansible/test block=aa'
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "msg": "Block inserted"
}
[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test"
10.15.43.13 | SUCCESS | rc=0 >>
1
22
333
# BEGIN ANSIBLE MANAGED BLOCK
aa
# END ANSIBLE MANAGED BLOCK

[root@Super ~]# 

删除标记

[root@Super ~]# ansible A -R root -S -m blockinfile -a 'path=/app/ansible/test block=aa marker=#{mark}test state=absent '
10.15.43.13 | SUCCESS => {
    "changed": false, 
    "msg": ""
}
[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test"
10.15.43.13 | SUCCESS | rc=0 >>
1
22
333
# BEGIN ANSIBLE MANAGED BLOCK
aa
# END ANSIBLE MANAGED BLOCK

[root@Super ~]# ansible A -R root -S -m blockinfile -a 'path=/app/ansible/test block=aa state=absent '
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "msg": "Block removed"
}
[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test"
10.15.43.13 | SUCCESS | rc=0 >>
1
22
333

[root@Super ~]# 

删除标记不但要标记的内容一致,而且开始标记、结束标记字段也要一致。

[root@Super ~]# ansible A -R root -S -m blockinfile -a 'path=/app/ansible/test block=aa marker=#{mark}test insertafter=2'
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "msg": "Block inserted"
}
[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/test"
10.15.43.13 | SUCCESS | rc=0 >>
1
22
#BEGINtest
aa
#ENDtest
333

[root@Super ~]# 

在指定位置插入标记。

[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/shell.sh"
10.15.43.13 | SUCCESS | rc=0 >>
#!/bin/bash
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ~]# ansible A -R root -S -m blockinfile -a 'path=/app/ansible/shell.sh block="###blockinfile test###" marker="#{mark}test" insertafter="^#!/bin/bash" backup=yes'
10.15.43.13 | SUCCESS => {
    "changed": true, 
    "msg": "Block inserted"
}
[root@Super ~]# ansible A -R root -S -m shell -a "cat /app/ansible/shell.sh"
10.15.43.13 | SUCCESS | rc=0 >>
#!/bin/bash
#BEGINtest
###blockinfile test###
#ENDtest
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ~]# 

匹配以#!/bin/bash开的行之后插入标记,并在操作前备份源文件。

* lineinfile模块

lineinfile模块可以确保"某一行文本"存在于指定的文件中,或者确保从文件中删除指定的"文本"(即确保指定的文本不存在于文件中),还可以根据正则表达式,替换"某一行文本"。

模块参数

参数 说明
path 必须参数,指定要操作的文件。
line 使用此参数指定文本内容。
regexp 使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,说都会被删除。
state 当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present
backrefs 默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes,backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了,backrefs=yes除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变。
insertafter 将文本插入到“指定的行”之后,insertafter参数的值可以设置为EOF或者正则表达式,EOF为End Of File之意,表示插入到文档的末尾,默认情况下insertafter的值为EOF,如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则的行之后,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。
insertbefore 将文本插入到“指定的行”之前,insertbefore参数的值可以设置为BOF或者正则表达式,BOF为Begin Of File之意,表示插入到文档的开头,如果将insertbefore的值设置为正则表达式,表示将文本插入到匹配到正则的行之前,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。
backup 是否在修改文件之前对文件进行备份。
create 当要操作的文件并不存在时,是否创建对应的文件。
[root@Super ~]# ansible A -S -R root -m lineinfile -a 'path=/app/ansible/zabbix_discovery_port.sh line="chmod +x /usr/local/zabbix/etc/discovertcpport.sh"'
10.15.43.15 | SUCCESS => {
    "backup": "", 
    "changed": false, 
    "msg": ""
}
[root@Super ~]# 

确保指定的"一行文本"存在于文件中,如果指定的文本本来就存在于文件中,则不做任何操作,如果不存在,默认在文件的末尾插入这行文本,如上命令表示确保"chmod +x /usr/local/zabbix/etc/discovertcpport.sh"这行文本存在于/app/ansible/zabbix_discovery_port.sh文件中。

[root@Super ~]# ansible A -S -R root -m lineinfile -a 'path=/app/ansible/zabbix_discovery_port.sh regexp="^systemctl.*" line="chmod +x /usr/local/zabbix/etc/discovertcpport.sh"'
10.15.43.15 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line added"
}
[root@Super ~]# ansible A -S -R root -m lineinfile -a 'path=/app/ansible/zabbix_discovery_port.sh regexp="^chmod.*" line="chmod +x /usr/local/zabbix/etc/discovertcpport.sh"'
10.15.43.15 | SUCCESS => {
    "backup": "", 
    "changed": false, 
    "msg": ""
}
[root@Super ~]# 

表示根据正则表达式替换"某一行",如果不止一行能够匹配正则,那么只有最后一个匹配正则的行才会被替换,被匹配行会被替换成line参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么line中的内容会被添加到文件的最后一行。

[root@Super ~]# ansible A -S -R root -m lineinfile -a 'path=/app/ansible/zabbix_discovery_port.sh regexp="^systemctl.*" line="chmod +x /usr/local/zabbix/etc/discovertcpport.sh" backrefs=yes'
10.15.43.15 | SUCCESS => {
    "backup": "", 
    "changed": false, 
    "msg": ""
}
[root@Super ~]# 

根据正则表达式替换"某一行",如果不止一行能够匹配正则,那么只有最后一个匹配正则的行才会被替换,被匹配行会被替换成line参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么则不对文件进行任何操作。

[root@Super ~]# ansible A -S -R root -m lineinfile -a 'path=/app/ansible/zabbix_discovery_port.sh regexp="^chmod.*" state=absent'
10.15.43.15 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "found": 2, 
    "msg": "2 line(s) removed"
}
[root@Super ~]#

根据正则表达式删除对应行,如果有多行都满足正则表达式,那么所有匹配的行都会被删除,也可以通过line指定具体内容来删除,例如line="chmod +x /usr/local/zabbix/etc/discovertcpport.sh"

  • 在匹配行前、后操作

添加

[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
#export LANG="zh_CN.UTF8"
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]# ansible 10.15.97.136 -S -R root -m lineinfile -a 'dest=/app/lineinfile.txt insertbefore="source" line=ansible'
10.15.97.136 | SUCCESS => {
    "backup": "",
    "changed": true,
    "msg": "line added"
}
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
#export LANG="zh_CN.UTF8"
export LANG="en_US.UTF-8"
ansible
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]#

在/app/lineinfile.txt中source行前添加一行ansible

替换

[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
#export LANG="zh_CN.UTF8"
export LANG="en_US.UTF-8"
ansible
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]# ansible 10.15.97.136 -S -R root -m lineinfile -a 'dest=/app/lineinfile.txt regexp="^#export" insertbefore="source" line=ansible'
10.15.97.136 | SUCCESS => {
    "backup": "",
    "changed": true,
    "msg": "line replaced"
}
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
ansible
export LANG="en_US.UTF-8"
ansible
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]#

将/app/lineinfile.txt文件中source之前的以#export开头的行替换成ansible,如果没有陪陪到#export就直接添加一行

  • 修改内容和权限
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt && ls -l /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
#export LANG="zh_CN.UTF8"
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile
-rw-r--r-- 1 root root 180 Sep 19 19:37 /app/lineinfile.txt

[root@Super ansible]# ansible 10.15.97.136 -S -R root -m lineinfile -a 'dest=/app/lineinfile.txt regexp="^#export" insertbefore="source" line=test owner=ywbz group=ywbz mode=755'
10.15.97.136 | SUCCESS => {
    "backup": "",
    "changed": true,
    "msg": "line replaced and ownership, perms or SE linux context changed"
}
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt && ls -l /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
test
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile
-rwxr-xr-x 1 ywbz ywbz 159 Sep 19 19:39 /app/lineinfile.txt

[root@Super ansible]#
  • 删除指定的行
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
#export LANG="zh_CN.UTF8"
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]# ansible 10.15.97.136 -S -R root -m lineinfile -a 'dest=/app/lineinfile.txt regexp="^#export" state=absent'
10.15.97.136 | SUCCESS => {
    "backup": "",
    "changed": true,
    "found": 1,
    "msg": "1 line(s) removed"
}
[root@Super ansible]# ansible 10.15.97.136 -m shell -a 'cat /app/lineinfile.txt'
10.15.97.136 | SUCCESS | rc=0 >>
#!/bin/bash
export LANG="en_US.UTF-8"
source /etc/rc.d/init.d/functions
[ -f /etc/profile ] && . /etc/profile
[ -f ~/.bash_profile ] && . ~/.bash_profile

[root@Super ansible]#

* replace模块

replace模块可以根据指定的正则表达式替换文件中的字符串,文件中所有被正则匹配到的字符串都会被替换。lineinfile的多行匹配版本,此模块会在文件中插入一段内容,并在内容开始和结束位置设置标签,后续可以使用标签可以对此块内容进行操作

参数 说明
path 必须参数,指定要操作的文件,2.3版本之前,只能使用dest, destfile, name指定要操作的文件,2.4之后的版本,仍然可以使用这些参数名,这些参数名作为path参数的别名使用。
regexp 必须参数,指定一个python正则表达式,文件中与正则匹配的字符串将会被替换。
replace 指定最终要替换成的字符串。
backup 是否在修改文件之前对文件进行备份,最好设置为yes。
[root@Super ~]# ansible A -S -R root -m replace -a 'path=/app/ansible/zabbix_discovery_port.sh regexp=".*restart.*" replace=deleted backup=yes'
10.15.43.15 | SUCCESS => {
    "backup_file": "/app/ansible/zabbix_discovery_port.sh.3933.2018-06-27@06:39:26~", 
    "changed": true, 
    "msg": "1 replacements made"
}
[root@Super ~]# 

* ini_file

主要是用来设置ini文件的格式的文件。

添加、删除、修改单独的ini格式的文件,其中主要是用来修改部分的配置信息,而不是template或者是assemble,添加失去的section。

参数 必填 默认 选择 说明
Backup No No Yes/no 在修改之前进行备份
Dest yes Ini类型文件的路径,如果不存在会创建
Follow No No Yes/no 标识是否文件系统链接,如果存在,那么将遵循
Group No 组名
Mode No 权限
Option 如果需要修改一个值,那么可以设置,如果添加删除一个整段,那么可以忽略
Others No 文件模块所使用的参数可以在这里使用
Owner No 用户名
Section Yes 在ini文件中的section名称,如果状态为present并且设置了一个值,那么会添加
State No Present Absent/Present 新增/删除
Value NO 这个值和option相关联,如果删除那么会忽略

例如:

[root@Super ansible]# ansible 10.15.97.136 -m ini_file -a 'dest=/app/soft/ini_file section=justin value=51cto mode=0755 backup=yes'
10.15.97.136 | SUCCESS => {
    "changed": false, 
    "msg": "OK", 
    "path": "/app/soft/ini_file", 
    "state": "absent"
}
[root@Super ansible]# 

* find模块

find模块可以在远程主机中查找符合条件的文件,就像find命令一样。

模块参数

参数 说明
paths 必须参数,指定在哪个目录中查找文件,可以指定多个路径,路径间用逗号隔开,此参数有别名,使用path或者别名name可以代替paths。
recurse 默认情况下,只会在指定的目录中查找文件,如果目录中还包含目录,ansible并不会递归的进入子目录查找对应文件,如果想要递归的查找文件,需要使用recurse参数,当recurse参数设置为yes时,表示在指定目录中递归的查找文件。
hidden 默认情况下,隐藏文件会被忽略,当hidden参数的值设置为yes时,才会查找隐藏文件。
file_type 默认情况下,ansible只会根据条件查找"文件",并不会查找"目录"或"软链接"等文件类型,可以通过file_type指定文件类型:any、directory、file、link 四种。
patterns 使用此参数指定需要查找的文件名称,支持使用shell(比如通配符)或者正则表达式去匹配文件名称,默认情况下,使用shell匹配对应的文件名,如果想要使用python的正则去匹配文件名,需要将use_regex参数的值设置为yes。
use_regex 默认情况下,find模块不会使用正则表达式去解析patterns参数中对应的内容,当use_regex设置为yes时,表示使用python正则解析patterns参数中的表达式,否则,使用glob通配符解析patterns参数中的表达式。
contains 使用此参数可以根据文章内容查找文件,此参数的值为一个正则表达式,find模块会根据对应的正则表达式匹配文件内容。
age 使用此参数可以根据时间范围查找文件,默认以文件的mtime为准与指定的时间进行对比,比如,如果想要查找mtime在3天之前的文件,那么可以设置age=3d,如果想要查找mtime在3天以内的文件,可以设置age=-3d,这里所说的3天是按照当前时间往前推3天,可以使用的单位有秒(s)、分(m)、时(h)、天(d)、星期(w)。
age_stamp 文件的时间属性中有三个时间种类,atime、ctime、mtime,当我们根据时间范围查找文件时,可以指定以哪个时间种类为准,当根据时间查找文件时,默认以mtime为准。
size 使用此参数可以根据文件大小查找文件,如果想要查找大于3M的文件,那么可以设置size=3m,如果想要查找小于50k的文件,可以设置size=-50k,可以使用的单位有t、g、m、k、b。
get_checksum 当有符合查找条件的文件被找到时,会同时返回对应文件的sha1校验码,如果要查找的文件比较大,那么生成校验码的时间会比较长。
[root@Super ~]# ansible A -S -R root -m find -a 'path=/app/ansible/ contains=".*discovertcpport.*"'
10.15.43.15 | SUCCESS => {
    "changed": false, 
    "examined": 2, 
    "files": [
        {
            "atime": 1530049067.714182, 
            "ctime": 1530049067.714182, 
                        ......
                        "path": "/app/ansible/zabbix_discovery_port.sh",

在目录中查找文件内容中包含discovertcpport字符串的文件,隐藏文件会被忽略,不会进行递归查找。

[root@Super ~]# ansible A -S -R root -m find -a 'path=/app/ansible/ contains=".*discovertcpport.*" recurse=yes'
10.15.43.15 | SUCCESS => {
    "changed": false, 
    "examined": 5, 
    "files": [
        ......
    "path": "/app/ansible/zabbix_discovery_port.sh",
        ......
        "path": "/app/ansible/chdir/chdir.sh",
        ......
        "path": "/app/ansible/chdir/chdir2/chdir-2.sh",
        ......

在目录及其子目录中查找文件内容中包含discovertcpport字符串的文件,隐藏文件会被忽略。

[root@Super ~]# ansible A -S -R root -m find -a 'path=/app/ansible/ patterns="*.sh" recurse=yes hidden=yes file_type=any'
10.15.43.15 | SUCCESS => {
    "changed": false, 
    "examined": 5, 
    "files": [
    ......
        "path": "/app/ansible/zabbix_discovery_port.sh",
        ......
        "path": "/app/ansible/chdir/chdir.sh",
        ......
        "path": "/app/ansible/chdir/chdir2/chdir-2.sh",
        ......

在目录及其子目录中查找以.sh结尾的文件,包括隐藏文件,包括所有文件类型,比如文件、目录、或者软链接。

[root@Super ~]# ansible A -S -R root -m find -a 'path=/app/ansible/ patterns=".*\.sh" use_regex=yes recurse=yes hidden=yes file_type=any'
10.15.43.15 | SUCCESS => {
    "changed": false, 
    "examined": 5, 
    "files": [
        .......
    "path": "/app/ansible/zabbix_discovery_port.sh",
        ......
        "path": "/app/ansible/chdir/chdir.sh",
        .......
        "path": "/app/ansible/chdir/chdir2/chdir-2.sh",
        .......

在目录及其子目录中中查找以.sh结尾的文件,只不过patterns对应的表达式为正则表达式,查找范围包括隐藏文件,包括所有文件类型,但是不会进行递归查找。


* assemble

用于组装文件,即将多个零散的文件,合并一个大文件

  • 常用参数:
参数 说明
attributes 文件或目录对应的属性,2.3后新增
backup 创建一个备份文件(如果yes),包括时间戳信息
decrypt 控制使用保管库对源文件进行自动解密,2.4后新增
delimiter 分隔文件内容的分隔符,1.4后新增
dest 使用所有源文件的连接创建的文件,合并后的大文件路径
group 合并后的大文件的所属组
owner 合并后的大文件的所属主
ignore_hidden 组装时,是否忽略隐藏文件,默认为no,2.0后新增
mode 合并后的大文件的权限。对于那些习惯于/usr/bin/chmod的记住,模式实际上是八进制数字(如0644or 01777)。离开前导零可能会有意想不到的结果。从版本1.8开始,可以将模式指定为符号模式(例如u+rwx或u=rw,g=r,o=r)
regexp 在regex匹配文件名时汇编文件。如果未设置,则所有文件都被组合。所有“\”(反斜杠)必须转义为“\”才能符合yaml语法
remote_src 如果为False,它将在本地主机上搜索src,如果为True,它将转到src的远程主机。默认值为True,1.4后新增
src 源文件(即零散文件)的路径
validate 与template的validate相同,指定命令验证文件,2.0后新增

例如:

 - name: Build the authorized_keys file 
   assemble: src=/opt/sshkeys/ dest=/root/.ssh/authorized_keys owner=root group=root mode=0700 

将/opt/sshkeys目录里所有的文件合并到/root/.ssh/authorized_keys一个文件中