copy模块
- 在前面小节中,我们已经了解了ping和fetch模块,但ansible有很多模块且每个模块也不同的功能,且模块内容比较多。所以对于日常使用的场景,我们只需了解常用的模块即可。如果需要了解更多,请参考官方手册。
- copy模块作用是用于拷贝文件,与之前的fetch模块类似。不同的是,fetch只是从远程主机拉取到ansible主机,而copy模块则是将ansible主机上的文件拷贝到远程主机中去。
此处我们介绍一下copy模块的相关参数- src: 用于指定需要copy的文件或目录,也就是源
- dest: 用于指定文件拷贝到远程的目录,也就是目的,且dest为必需参数,否帽执行命令将会报错
- content: 当不使用src指定拷贝的文件时,可以使用content直接指定文件内空,src与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表示。
- 对应上面参数说明我们来做下面的测试
ansible 192.168.3.41 -m copy -a "src=/root/test.log dest=/opt/"
-
未报错后登陆192.168.3.41 查看/opt下面的文件是否存在
查看文件copy推送至远程主机
-
我们再进行如下操作,在远程主机192.168.3.41主机上面/opt目录下面 我们vim test文件,文件分成两行,第一行aaa,第二行bbb
ansible 192.168.3.41 -m copy -a 'content="aaa\nbbb\n" dest=/opt/1.log'
- 将ansible主机中 /testdir/copytest 文件复制到远程主/opt目录中,如果远程主机已存在/opt/copytest文件,并且文件内容与ansible主机中的copytest文件内容不一致,则不很乖拷贝操作,远程主机中的/opt/copytest文件内容不会变。此处相当于是否强制性copy 相当liunx cp命令下的 cp -f
ansible 192.168.3.41 -m copy -a "src=/testdir/copytest dest=/opt/ force=no"
- 将ansible主机中的/testdir/copytest文件复制到远程主机的/opt目录中时,如果远程主机存在copytest文件,并且文件内容与ansible主机内容的copytest文件不一致时,会执行拷贝操作,但是在执行拷贝操作之前,会在执行拷贝之前,将远程主机的原文件名重命名,备份后再执行拷贝。此时备份文件会有个时间戳结尾的备份文件产生 新的文件同时也会存在。
- 拷贝文件时,指定文件的所属关,
但注意的问题是,远程主机上必须存在对应的用户及组
ansible 192.168.3.41 -m copy -a "src=/testdir/copytest dest=/opt/ owner=zsy" ansible 192.168.3.41 -m copy -a "src=/testdir/copytest dest=/opt/ group=zsy"
- 拷贝文件时,指定文件的权限
ansible 192.168.3.41 -m copy -a "src=/testdir/copytest dest=/opt/ mode=0755"
-
file模块使用方法
- file模块可以帮忙我们完成对一些文件的基本操作,比如:创建文件目录,删除文件及目录,修改文件权限等。那么下面我们来介绍一下file模块常用的参数,然后再给出对应示例。
- path参数: path参数为必需参数,用于指定要操作的文件或目录,在之前的版本中的anisble中,使用dest参数或name参数指定要操作的文件或目录,为了兼容其之前的版本,使用dest或name也可以执行。
- state参数:些参数可以灵活设置,对应的值需要根据情况设定。比如,当我们需要在远程主机中创建一个目录时,我们需要使用path参数来指定对应的目录路径,如果我们想在主机上创建/testdir/test/1目录时,那么我们就可以设置为path=/testdir/test/1。但是,我们无法从/testdir/test/1这个路径看出是个目录还是个文件,ansible也同样不法从这个路径是创建一个文件还是目录。所以我们需要通要state参数进行说明,当我们想创建 /testdir/test/1是一个文件时,则需要将state的值设置为touch,当我们想要创建软链接时,需要将state设置为link。当想要创建硬链接时,需要将state设置为hard。当我们想要删除一个文件时(删除时不用区分目标还是文件、目录还是链接)则需要将state设置为absent(缺席),当我们想让目标“缺席”即表示我们要删除目标。
- src参数: 当state设置为link或hard时,表示我们想要创建一个软链接或硬链接。所以,我们必须指明软硬链接的那个源文件,通过src参数即可指定链接源。
- force参数: 当state=link的时候,可配合此参数强制创建链接文件,当force=yes时,表示强制创建链接文件,不过强制创建链接的文件分两种:1:当创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。2:当要创建的链接文件的目录已存在或者链接文件同名时,将force设置为yes,会将同名文件覆盖文件为链接文件,相当于删除同名文件,创建链接文件。3.当创建文链接文件中的目录已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制 替换为同名文件为链接文件。
- owner参数: 用于指定被操作文件的属主,属主对应用记必须在远程主机上存在,否则报错。
- group参数: 同上用于组别
- mode参数: 用于指定被操作文件的权限。比如,若想将文件权限设置为“rw-r-x---”,则可以使用mode=650进行设置,或者使用mode=0650,效果等同。若你想要设置特殊的权限 ,比如二进制文件设置的suid,则可以使用mode=4700。
- recurse参数: 当要操作的文件为目录,将recuse设置为yes,可以递归的修改目录中的文件属性。
操作演示
- 在192.168.3.41主机上面创建一个名为testfile的文件,如果testfile文件已存在,则会更新时间戳,与touch命令作用相同。
ansible 192.168.3.41 -m file -a "path=/testdir/testfile state=touch"
- 在192.168.3.41主机创建一个名为testidir的目录,如果testdir目录已存在,则不操作任何操作。
ansible 192.168.3.41 -m file -a "path=/testdir/testdir state=directory"
- 在192.168.3.41主机上为testfile文件创建软链接文件,软链接名为linkfile,执行如下命令的时候,testfile文件已存在。
ansible 192.168.3.41 -m file -a "path=/testdir/linkfile state=link src=/testdir/testfile"
- 在192.168.3.4主机上为testfile文件硬链接文件,软链接名为hardfile,执行如下命令的时候,testfile文件已存在。
ansible 192.168.3.41 -m file -a "path=/testdir/hardfile state=link src=/testdir/testfile"
- 在创建链接文件时,如果源文件不存在,或者链接文件与其他文件名同名时,强制覆盖同名文件或者创建链接文件,参考上述force参数。
ansible 192.168.3.41 -m file -a "path=/testdir/linkfile state=link src=sourcefile force=yes"
- 删除远程主机上指定的文件或目录
ansible 192.168.3.41 -m file -a "path=/testdir/testdir state=absent"
- 在创建文件或目录的时候指定属主,或者修改远程主机上的文件或目录的属主。
ansible 192.168.3.41 -m file -a "path=/testdir/abc state=touch owner=zsy"
ansible 192.168.3.41 -m file -a "path=/testdir/abc owner=zsy"
ansible 192.168.3.41 -m file -a "path=/testdir/abc state=directory owner=zsy"
- 在创建文件或目录时指定用户属组,或者修改远程主机上的文件或目录的属主。
ansible 192.168.3.41 -m file -a "path=/testdir/abb state=touch group=zsy"
ansible 192.168.3.41 -m file -a "path=/testdir/abb group=zsy"
ansible 192.168.3.41 -m file -a "path=/testdir/abb state=directory group=zsy"
- 在创建文件或目录时,指定权限,或者修改远程主机的文件或目录的权限。
ansible 192.168.3.41 -m file -a "path=/testdir/abb state=touch mode=0644"
ansible 192.168.3.41 -m file -a "path=/testdir/abb mode=0644"
ansible 192.168.3.41 -m file -a "path=/testdir/binfile mode=4700"
ansible 192.168.3.41 -m file -a "path=/testdir/abb state=directory mode=0644"
- 当操作主机中的目录时,同时递归的将目录的文件的属主属组都设置为zsy
ansible 192.168.3.41 -m file -a "path=/testdir/abc state=directory owner=zsy group=zsy recurse=yes"
blockinfile模块
blockinfile模块可以帮助我们在指定的文件中插入一段“文本”,这段文件是被标记的,换句话说就是,我们在这段文件上做了记号,以便在以后的操作可以通过“标记”找到这段文本。然后进行修改或删除。单靠这样的描述不容易理解,结合下面的示例应该就很快的明白了。
blockinfile常用参数
- path参数: 必需参数,指定要操作的文件
- block参数: 此参数用于我们指定的那一段“文本”,此参数有个别名叫“content”,与此同时使用content和block的作用效果是等同的。
- marker参数: 假如我们想要在指定的文件中插入一段文件,ansible会自动为这段文本添加两个标记,一个开始标记,一个结束标记。在默认情况下,开始标记为#BEGIN ANSIBLE AMNAGED BLOCK,结束以#END ANSIBLE AMNAGED BLOCK。 我们可以使用marcker参数自定义“标记”。比如,maker=#{mark}test,这样设置的话开始标记变成了# BEGIN test,{mark}会自动被替换成开始标记和结束标记中的BEGIN和END,像我们可以插入很多文件本,为不同的段落添加不同的标记,下次通过对应的标记即可找到对应的段落。
- state参数:state参数有两个值可选,present与absent。默认情况下,我们会将指定的一璺文件“插入”到文件中去。如果对应的文件中已经存在对就的标记的文本,默认会更新对应段落。在执行插入操作或更新操作时,state的值为present, 如果对应的文件中已经存在对应标记的文件本且将state的值设置为absent,则表示从文件中删除对应标记的段落。
- insertafter参数: 在插入一段文本时,默认会在文件的末尾插入文本。如果你想将文本插入在某一行的后面,可以使用些参数指定对应的行,也可以使用正则表达式(pyhthon正则),表示将文本插入在符合正则表达式行的后面。如果有多行文本都能匹配对应的正则表达式,则又以后最后一个东路正则的行为为准。此参数的值还可以设置成EOF,表示将文本插入到文档的末尾行。
- insertbefore参数: 在插入一段文本时,默认会在文件的末尾插入文本。如果你想将文本插入在某一行的后面,可以使用些参数指定对应的行,也可以使用正则表达式(pyhthon正则),表示将文本插入在符合正则表达式行的前面。如果有多行文本都能匹配对应的正则表达式,则又以后最后一个东路正则的行为为准。此参数的值还可以设置成BOF,表示将文本插入到文档的开头。
- backup参数: 是否在修改文件之前对文件进行备份。
- create参数: 当操作的文件并不存在时,是否创建对应的文件。
实际操作举例
为方便举例,我们将/etc/rc.d/rc.local文件复制到/testdir目录中去,以做测试 :cp cp /etc/rc.d/rc.local /testdir/
我们在/testdir/rc.local文件末尾添加两行命令
#BEGIN service to start
systemctl start nginx
systemclt start httpd
#END service to start
- 在执行如上操作时,执行如下命令:
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/rc.local block="" marker="#{mark} serivce to start" '
- 因在执行此命令时,“#{make}service to start”标记对应的文本已存在于文件中,而同时blockinfile模块会删除对应标记的文本内容。我们便可执行如下删除对应的模块文本,效果等同。
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/rc.local marker="#{mark} service to start" state=absent'
-
执行前后对比
- 将state的值设置为 absent,表示删除对应的文本块。
- 默认情况下,广西块插入在文本的情尾部。我们可以将广西块插入到指定位置。比如,文件开头,或者根据正则表达式去匹配对应的行。然后将文本块插入到匹配的行前面或末尾。
- 如果想要将文本块插入到文档的开头,那么可以使用insertbefore参数,将其值设置为BOF,BOF表示Begin Of File
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/rc.local block="####blockinfile test####" marker="#{mark} ansible" i
nsertbefore=BOF'
- 同理在文本末尾添加 则为EOF End Of File
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/rc.local block="####blockinfile test####" marker="#{mark} ansible" i
nsertbefore=EOF'
mark标记字段也可以为中文
- 正则表达式使用 如下表示使用正则表达式匹配行,将文本块插入到以“#!/bin/bash”之后的行(之前则insertbefore)。
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/rc.local block="####ansible blockinfile test####" marker="#{mark} test reg" insertafter="^#!/bin/bash" '
- backup参数示例,用此参数可以在操作修改文件前,对文件进行备份,备份的文件会在原文件名的基础上添加时间戳。(过滤标记格式,请参考原来的标记是什么 如有空格必定要加上,否则不出现remove删除提示)
ansible 192.168.3.41 -m blockfile -a 'path=/testdir/rc.local marker="#{mark} ansible" state=absent backup=yes'
- creat参数 ,如果指定的文件不存在,则创建它。此功亦匹配是否存在文件,若不存再则创建,并写入内容示例如下:
ansible 192.168.3.41 -m blockinfile -a 'path=/testdir/test block="ansible" marker="#{mark} ansible" create=yes'
lineinfile模块
我们可以借用lineinfile模块,确保“某一行文本”存在于指定的文件中,或者确保从文件中删除指定文本(即确保指定的文本不存在于文件中)。还可以根据正则表达式,替换“某一行文件” 通俗的讲这个相当于liunx的sed命令。
接下来我们看一下lineinfile模块常用的一些参数
- path参数 必须参数,指定文件路径
- line 使用此参数指定文本内容
- regexp 使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能匹配,则只有最后面被匹配的那行文本才能被替换。当删除文件时,如果有多行文本能被匹配,那么这些行都会删除。
- state 当想想删除对应的文本时,需要将state参数设置为absent, state默认值为present。这和之前模块参数表达意思一致。
- backrefs 默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对与正则中的分组进行引用,除非将backrefs参数设置为yes,backrefs=yes,这样line参数中就能对regexp参数中的分组进行后向引导,这样讲不太直观,可以参考下面示例命令可能会比较直观一些。backrefs=yes除了能够开启后向引导功能,还有另一个作用,默认情况下,当使用了正则表达式替换对应行时,如果正则没有匹配任何内容,那么line对应的内容会被插入到文本末,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes。那么当正则没有匹配到任何行时,则不会对文件 进行任何操作,相当于保持原有文件不变。
- insertafter 借助insertafter参数可以将文本插入到“指定的行”之后,insertafter参数值可以设置为EOF或正则表达式,EOF为End Of File,表示插入到文本末尾,默认情况下insertafter的值为EOF。如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则之后的行,如果正则没有匹配到任何行,则插入到广西末尾,当使用backrefs参数时,此参数被忽略。
- insertbefore 与之相反
- backup 是否在修改文件备份
- create参数 当要操作的文件不存在时,是否创建对应的文件
lineinfile示例操作
我们新建立files文件
# cat /testdir/test
Hello ansible,Hiiii
lineinfile -
Ensure a particular line is in a file,
lineinfile -
or replace an existing line using a back-referenced regular expression.
- 确保指定的“一行文本”存在于文件中,如果指定的文件文本本来就在文件中,则不做任何操作。如果不存在,默认在文件的末尾插入这行文本,如下命令表示确保“test lineinfile”这行文本存在于/testdir/test文件中。
ansible 192.168.3.41 -m lineinfile -a 'path=/testdir/test line="test text"'
- 如下 命令表示根据正则表达式替换“某一行”,如果不止一行能够匹配正则,那么只有最后个匹配正则的行才会补替换,被匹配行会被替换成line参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么line中的内容会被添加到文件的最后一台。
ansible 192.168.3.41 -m lineinfile -a 'path=/testdir/test regexp="^line" line="test text" '
- 如下 命令表示根据正则表达式替换“某一行”,如果不止一行能够匹配正则,那么只有最后个匹配正则的行才会补替换,被匹配行会被替换成line参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么不对文件进行任何操作
ansible 192.168.3.41 -m lineinfile -a 'path=/testdir/test regexp="^line" line="test text" backrefs=yes '
- 根据line参数的内容删除行,如果有多行都满足都与line参数内容相同,那么这些相同的行会被删除。
ansible 192.168.3.41 -m lineinfile path=/testdir/test line="lineinfile -" state=absent'
- 根据正则表达式删除对应的行,如果有多行季满足正则表达式,那么所有匹配的行都会被删除。
ansible 192.168.3.41 -m lineinfile -a 'path=/testdir/test regexp="^lineinfile" state=absent'
- 默认情况下,lineinfile模块不支持向后的引用
- 其他模块说明及用法,insertafter,insertbefore,backup,create不再举例,可参考blockinfile模块。