2023年12月1日发(作者:)

ansible常⽤模块---对⽂件的操作模块详解⼀(copyfileblockinfi。。。

模块

(1)模块介绍

见名知义,copy模块的作⽤就是拷贝⽂件,它与之前介绍的fetch模块类似,不过,fetch模块是从远程主机中拉取⽂件到ansible主机,⽽

copy模块是将ansible主机上的⽂件拷贝到远程主机中。

(2)模块参数

此处我们介绍⼀些copy模块的常⽤参数,然后再给出对应⽰例。

参数含义

src参数⽤于指定需要copy的⽂件或⽬录

dest参

content

参数

force参当远程主机的⽬标路径中已经存在同名⽂件,并且与ansible主机中的⽂件内容不同时,是否强制覆盖,可选值有yes和no,默认值为yes,表⽰

覆盖,如果设置为no,则不会执⾏覆盖拷贝操作,远程主机中的⽂件保持不变。

backup当远程主机的⽬标路径中已经存在同名⽂件,并且与ansible主机中的⽂件内容不同时,是否对远程主机的⽂件进⾏备份,可选值有yes和no,当

参数设置为yes时,会先备份远程主机中的⽂件,然后再将ansible主机中的⽂件拷贝到远程主机。

owner

参数

group

参数

mode参指定⽂件拷贝到远程主机后的权限,如果你想将权限设置为"rw-r–r–",则可以使⽤mode=0644表⽰,如果你想要在user对应的权限位上添加

执⾏权限,则可以使⽤mode=u+x表⽰。

⽤于指定⽂件将被拷贝到远程主机的哪个⽬录中,dest为必须参数

当不使⽤src指定拷贝的⽂件时,可以使⽤content直接指定⽂件内容,src与content两个参数必有其⼀,否则会报错。

指定⽂件拷贝到远程主机后的属主,但是远程主机上必须有对应的⽤户,否则会报错。

指定⽂件拷贝到远程主机后的属组,但是远程主机上必须有对应的组,否则会报错。

模块⽰例

对应上述参数的命令如下:

将ansible主机中/testdir/copytest⽂件复制到远程主机的/opt⽬录下,注意,如果copytest⽂件已经存在于远程主机的/opt⽬录中,并

且远程主机中的copytest与ansible主机中copytest⽂件内容不同,那么使⽤如下命令时,远程主机中的copytest⽂件将被覆盖。

在server4中只执⾏:

ansible testB -m copy -a "src=/testdir/copytest dest=/opt/"

上图可以看出内容已经被覆盖

在远程主机的/opt⽬录下⽣成⽂件test1,test1⽂件中有两⾏⽂本,第⼀⾏⽂本为aaa,第⼆⾏为bbb,当使⽤content指定⽂件内容

时,dest参数对应的值必须是⼀个⽂件,⽽不能是⼀个路径。

ansible testB -m copy -a 'content="aaanbbbn" dest=/opt/test1'

将ansible主机中/testdir/copytest⽂件复制到远程主机的/opt⽬录中时,如果远程主机中已经存在/opt/copytest⽂件,并且⽂件内容与

ansible主机中的copytest⽂件的内容不⼀致,则不执⾏拷贝操作,远程主机中的/opt/copytest⽂件内容不会被改变。

ansible testB -m copy -a "src=/testdir/copytest dest=/opt/ force=no"

将ansible主机中/testdir/copytest⽂件复制到远程主机的/opt⽬录中时,如果远程主机中已经存在/opt/copytest⽂件,并且⽂件内容与

ansible主机中的copytest⽂件的内容不⼀致,会执⾏拷贝操作,但是在执⾏拷贝操作之前,会将远程主机中的原⽂件重命名,以作备份,

然后再进⾏拷贝操作。

ansible testB -m copy -a "src=/testdir/copytest dest=/opt/ backup=yes"

拷贝⽂件时,指定⽂件的属主,需要注意,远程主机上必须存在对应的⽤户。

执⾏后

拷贝⽂件时,指定⽂件的属组,需要注意,远程主机上必须存在对应的组。

ansible testB -m copy -a "src=/testdir/copytest dest=/opt/ group=dd"

执⾏后

拷贝⽂件时,指定⽂件的权限

ansible testB -m copy -a "src=/testdir/pp dest=/opt mode=0640"

当⽬标⽂件存在且相同时,只会更改权限:

ansible testB -m copy -a "src=/testdir/copytest dest=/opt mode=0640"

模块

模块介绍

file模块可以帮助我们完成⼀些对⽂件的基本操作,⽐如,创建⽂件或⽬录、删除⽂件或⽬录、修改⽂件权限等

模块参数

此处我们介绍⼀些file模块的常⽤参数,然后再给出对应⽰例。

参数含义

path参必须参数,⽤于指定要操作的⽂件或⽬录,在之前版本的ansible中,使⽤dest参数或者name参数指定要操作的⽂件或⽬录,为了兼容之前的版

本,使⽤dest或name也可以。

此参数⾮常灵活,此参数对应的值需要根据情况设定,⽐如,当我们需要在远程主机中创建⼀个⽬录的时候,我们需要使⽤path参数指定对应的

⽬录路径,假设,我想要在远程主机上创建/testdir/a/b⽬录,那么我则需要设置path=/testdir/a/b,但是,我们⽆法从"/testdir/a/b"这个路

径看出b是⼀个⽂件还是⼀个⽬录,ansible也同样⽆法单单从⼀个字符串就知道你要创建⽂件还是⽬录,所以,我们需要通过state参数进⾏说

state参明,当我们想要创建的/testdir/a/b是⼀个⽬录时,需要将state的值设置为directory,"directory"为⽬录之意,当它与path结合,ansible就

能知道我们要操作的⽬标是⼀个⽬录,同理,当我们想要操作的/testdir/a/b是⼀个⽂件时,则需要将state的值设置为touch,当我们想要创建

软链接⽂件时,需将state设置为link,想要创建硬链接⽂件时,需要将state设置为hard,当我们想要删除⼀个⽂件时(删除时不⽤区分⽬标是

⽂件、⽬录、还是链接),则需要将state的值设置为absent,"absent"为缺席之意,当我们想让操作的⽬标"缺席"时,就表⽰我们想要删除⽬

标。

参数含义

owner参数 ⽤于指定被操作⽂件的属主,属主对应的⽤户必须在远程主机中存在,否则会报错。

group参数 ⽤于指定被操作⽂件的属组,属组对应的组必须在远程主机中存在,否则会报错。

建链接⽂件的⽬录中已经存在与链接⽂件同名的⽂件,并且链接⽂件指向的源⽂件也不存在,这时会强制替换同名⽂件为链接⽂件。

参数 ⽤于指定被操作⽂件的权限,⽐如,如果想要将⽂件权限设置为"rw-r-x—",则可以使⽤mode=650进⾏设置,或者使⽤mode=0650,效

果也是相同的,如果你想要设置特殊权限,⽐如为⼆进制⽂件设置suid,则可以使⽤mode=4700,很⽅便吧。

参数 当要操作的⽂件为⽬录,将recurse设置为yes,可以递归的修改⽬录中⽂件的属性。recurse

mode

模块⽰例

对应上述参数的⽰例命令如下:

在testB(server3)主机上创建⼀个名为westos的⽂件,如果testfile⽂件已经存在,则会更新⽂件的时间戳,与touch命令的作⽤相同。

在server4:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/westos state=touch"

当远程主机中⽂件已经从在再次执⾏命令依然会成功,会修改远程主机⽂件的时间戳:

在testB(server3)主机上创建⼀个名为westosdir的⽬录,如果westosdir⽬录已经存在,则不进⾏任何操作

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/westosdir state=directory"

执⾏结果:

再次执⾏未进⾏任何操作

在testB(server3)上为westos⽂件创建软链接⽂件,软链接名为linkwestos,执⾏下⾯命令的时候,westos已经存在。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/linkwestos state=link src=/testdir/westos"

执⾏后

在testB(server3)上为westos⽂件创建硬链接⽂件,硬链接名为hardwestos,执⾏下⾯命令的时候,westos已经存在。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/hardwestos state=hard src=/testdir/westos"

在创建链接⽂件时,如果源⽂件不存在,或者链接⽂件与其他⽂件同名时,强制覆盖同名⽂件或者创建链接⽂件,参考上述force参数的解

释。

源⽂件不存在并且链接⽂件与其他⽂件同名:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/linkwestos state=link src=westos-dd force=yes"

删除远程机器上的指定⽂件或⽬录

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/linkwestos state=absent"

在创建⽂件或⽬录的时候指定属主,或者修改远程主机上的⽂件或⽬录的属主。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/a state=touch owner=dd"

在创建⽂件或⽬录的时候指定属组,或者修改远程主机上的⽂件或⽬录的属组。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/b state=touch group=dd"

当⽂件存在时只修改属组:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/a state=touch group=dd"

指定⽬录的属组:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/c state=directory group=dd"

修改⽬录的属主:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/c state=directory owner=dd"

在创建⽂件或⽬录的时候指定权限,或者修改远程主机上的⽂件或⽬录的权限。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/c mode=666"

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/d state=directory mode=0644"

指定特殊权限:

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/d state=directory mode=2700"

当操作远程主机中的⽬录时,同时递归的创建⽬录并将⽬录中的⽂件的属主属组都设置为dd。

[root@server4 testdir]# ansible testB -m file -a "path=/testdir/1/2 state=directory owner=dd group=dd recurse=yes"

nfile模块

模块介绍

blockinfile模块可以帮助我们在指定的⽂件中插⼊"⼀段⽂本",这段⽂本是被标记过的,换句话说就是,我们在这段⽂本上做了记号,以便

在以后的操作中可以通过"标记"找到这段⽂本,然后修改或者删除它,单单这样描述不是特别容易理解,结合下⾯的⼩例⼦动⼿做做⽴马就

能够明⽩了。

模块参数

此处我们介绍⼀些blockinfile模块的常⽤参数,你可以先对这些参数有⼀个⼤概了解,然后再看⼩⽰例。

参数含义

path参数必须参数,指定要操作的⽂件。

block参数此参数⽤于指定我们想要操作的那"⼀段⽂本",此参数有⼀个别名叫"content",使⽤content或block的作⽤是相同的。

假如我们想要在指定⽂件中插⼊⼀段⽂本,ansible会⾃动为这段⽂本添加两个标记,⼀个开始标记,⼀个结束标记,默认情况下,开始标

记为# BEGIN ANSIBLE MANAGED BLOCK,结束标记为# END ANSIBLE MANAGED BLOCK,我们可以使⽤marker参数⾃定

marker参数义"标记",⽐如,marker=#{mark} test ,这样设置以后,开始标记变成了# BEGIN test,结束标记变成了# END test,没错,{mark}

会⾃动被替换成开始标记和结束标记中的BEGIN和END,我们也可以插⼊很多段⽂本,为不同的段落添加不同的标记,下次通过对应的标

记即可找到对应的段落。

state参数有两个可选值,present与absent,默认情况下,我们会将指定的⼀段⽂本"插⼊"到⽂件中,如果对应的⽂件中已经存在对应标

state参数记的⽂本,默认会更新对应段落,在执⾏插⼊操作或更新操作时,state的值为present,默认值就是present,如果对应的⽂件中已经存在

对应标记的⽂本并且将state的值设置为absent,则表⽰从⽂件中删除对应标记的段落。

在插⼊⼀段⽂本时,默认会在⽂件的末尾插⼊⽂本,如果你想要将⽂本插⼊在某⼀⾏的后⾯,可以使⽤此参数指定对应的⾏,也可以使⽤正

则表达式(python正则),表⽰将⽂本插⼊在符合正则表达式的⾏的后⾯,如果有多⾏⽂本都能够匹配对应的正则表达式,则以最后⼀个满⾜

正则的⾏为准,此参数的值还可以设置为EOF,表⽰将⽂本插⼊到⽂档末尾。

在插⼊⼀段⽂本时,默认会在⽂件的末尾插⼊⽂本,如果你想要将⽂本插⼊在某⼀⾏的前⾯,可以使⽤此参数指定对应的⾏,也可以使⽤正

则表达式(python正则),表⽰将⽂本插⼊在符合正则表达式的⾏的前⾯,如果有多⾏⽂本都能够匹配对应的正则表达式,则以最后⼀个满⾜

正则的⾏为准,此参数的值还可以设置为BOF,表⽰将⽂本插⼊到⽂档开头。

是否在修改⽂件之前对⽂件进⾏备份。backup参数

当要操作的⽂件并不存在时,是否创建对应的⽂件。create参数

insertafter

参数

insertbefore

参数

模块⽰例

对应上述参数的⽰例命令如下:

为了⽅便举例,我们将/etc/rc.d/⽂件复制到/testdir⽬录中,以做测试

假如,我们想要在testB(server3)主机中的/testdir/⽂件尾部插⼊如下两⾏

systemctl start mariadb

systemctl start nfs

可以使⽤

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="systemctl start mariadbnsystemctl start nfs"'

使⽤path参数指定要操作的⽂件,使⽤block参数指定⽂本块内容,我们使⽤n表⽰换⾏,在写ansible剧本时则可以直接将⽂本块写在多

正如之前所说,blockinfile模块的作⽤就是在⽂件中添加、更新、或者删除"被标记的⽂本块",⽽上述被标记的⽂本块就是我们添加进⽂件

的, 就是blockinfile模块⾃动为我们添加的⽂本块标记,⼀个是开

# BEGIN ANSIBLE MANAGED BLOCK # END ANSIBLE MANAGED BLOCK

始标记,⼀个是结束标记。

我们也可以⾃定义标记,但是⾃定义的标记仍然要"成对出现",需要有开始标记和结束标记,⽰例如下

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="systemctl start mariadbnsystemctl start nfs" marker="#{mark} service to

start"'

vim

使⽤marker可以⾃定义⽂本块的标记, 上例中的"{mark}" 会⾃动被替换成开始标记中的"BEGIN" 和结束标记中的 “END”,如果⽂件中

不存在同名标记的⽂本块,那么⽂件的末尾将会出现如下⽂本块。

#BEGIN serivce to start

systemctl start mariadb

systemctl start nfs

#END serivce to start

当标记的⽂本块相同,⽽更新的内容不同,会覆盖之前更新的内容

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="systemctl start mariadb" marker="#{mark} service to start"'

vim

因为在执⾏此命令时,"#{mark} serivce to start"标记对应的⽂本块已经存在于⽂件中,⽽同时,block参数对应的内容⼜与之前⽂本块的

内容不同,所以,这种情况下,对应⽂本块中的内容会被更新,⽽不会再⼀次插⼊新的⽂本块,这种⽤法相当于更新原来⽂本块中的内容,

执⾏上述命令后,⽂本块的内容被更新为如下⽂本。

在执⾏完上述命令的基础上,执⾏如下命令

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="" marker="#{mark} service to start"'

在执⾏此命令时,"#{mark} serivce to start"标记对应的⽂本块已经存在于⽂件中,⽽同时,block参数对应的内容为空,这

vim

使⽤如下命令表⽰使⽤正则表达式匹配⾏,将⽂本块插⼊到 “以#!/bin/bash开头的⾏” 之后(同样需要将上个⽰例的内容删除)

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="#######blockinfile test#####" marker="#{mark} test" insertafter="^#!/bi

n/bash"'

vim

使⽤backup参数,可以在操作修改⽂件之前,对⽂件进⾏备份,备份的⽂件会在原⽂件名的基础上添加时间戳

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/ block="#######blockinfile test#####test ####" marker="#{mark} test" insertaft

er="^#!/bin/bash" backup=yes'

vim

使⽤create参数,如果指定的⽂件不存在,则创建它,⽰例如下

[root@server4 testdir]# ansible testB -m blockinfile -a 'path=/testdir/test block="###test###" marker="#{mark} test" create=yes'

4. lineinfile模块

模型介绍

我们可以借助lineinfile模块,确保"某⼀⾏⽂本"存在于指定的⽂件中,或者确保从⽂件中删除指定的"⽂本"(即确保指定的⽂本不存在于⽂

件中),还可以根据正则表达式,替换"某⼀⾏⽂本"。

模型参数

此处我们介绍⼀些lineinfile模块的常⽤参数,你可以先对这些参数有⼀个⼤概了解,然后再看⼩⽰例。

参数⽰例

path参数必须参数,指定要操作的⽂件。

line参数使⽤此参数指定⽂本内容。

使⽤正则表达式匹配对应的⾏,当替换⽂本时,如果有多⾏⽂本都能被匹配,则只有最后⾯被匹配到的那⾏⽂本才会被替换,当删除⽂本

时,如果有多⾏⽂本都能被匹配,这么这些⾏都会被删除。

当想要删除对应的⽂本时,需要将state参数的值设置为absent,absent为缺席之意,表⽰删除,state的默认值为presentstate参数

默认情况下,当根据正则替换⽂本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进⾏引⽤,除⾮将

backrefs参数的值设置为yes,backrefs=yes表⽰开启后向引⽤,这样,line参数中就能对regexp参数中的分组进⾏后向引⽤了,这样说

regexp参数

backrefs参不太容易明⽩,参考下⾯的⽰例命令⽐较直观⼀点,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参数

insertafter

参数

insertbefore

参数

模型⽰例

对应上述参数的ad-hoc⽰例命令如下:

为了⽅便举例,我们使⽤/testdir/test⽂件作为被操作的⽂件,test⽂件内容如下

# cat /testdir/test

Hello ansible!!

lineinfile -

Ensure a particular line is in a file,

lineinfile -

执⾏以下命令:

[root@server4 testdir]# ansible testB -m lineinfile -a 'path=/testdir/test regexp="^line" state=absent'

即所有匹配到的⾏都被删除了。

默认情况下,lineinfile模块不⽀持后向引⽤。

其他参数与之前的内容相同,就不再举例。