ansible shell模块:shell命令中带元字符、通配符的解决方法

一、ansible替换遇到的问题

ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换 。其实在ansible自身提供了两个模块---lineinfile模块和replace模块,可以方便的进行替换 。这里以使用ansilble安装salt-minion为例,用如下playbook语句执行时,是执行不成功的:shell: sed -i '/^#id:/a\id: {{ ansible_ens192.ipv4.address }}' /etc/salt/minion

由于上面的语名里特殊符号比较多,多次转义测试不成功。同样直接调用shell 模块时也会遇到这样问题,比如这里有一个将/etc/hosts最后一行注释的语句,使用$s 变量时会不成功,需要通过 \进行转义 。
例一:
ansible all -m shell -a "sed -e '$s/^/#/g' /etc/hosts" //不成功
ansible all -m shell -a "sed -i '\$s/#//g' /etc/hosts" //成功
例二:
ansible all -m raw -a "ps aux | grep xx | awk '{print \$2}' "   //成功
ansible all -m raw -a "ps aux | grep xx | awk '{print $2}' "    //不成功。会返回整行ps后的结果,而不只是打印pid
ansible all -m raw -a 'ps aux | grep xx | awk "{print \$2}" '   //不成功 
ansible all -m raw -a 'ps aux | grep xx | awk \'{print \$2}\' ' //不成功 
例三:
ansible -i esbhosts esbgroup -m shell -a 'echo $HOSTNAME'   //成功
ansible -i esbhosts esbgroup -m shell -a "echo $HOSTNAME"   //不成功 
例四:
root@drfdai:~# ansible 192.168.0.41 -m shell  -a "  ls /root/aa/{a1,a2}/1.log"   
192.168.0.41 | FAILED | rc=2 >>
ls: 无法访问/root/aa/{a1,a2}/1.log: 没有那个文件或目录
显然是执行失败了,提示没有/root/aa/{a1,a2}/1.log这个文件目录。这里,应该是ansible的shell模块,并不会解释元字符。

要解决这个问题,其实,只要用以下的方法就OK了:
root@drfdai:~# ansible 192.168.0.41 -m shell  -a "/bin/bash -c 'ls /root/aa/{a1,a2}/1.log'"
192.168.0.41 | success | rc=0 >>
/root/aa/a1/1.log
/root/aa/a2/1.log

这里,应该是ansible的shell模块,并不会解释元字符,要了解shell的元字符知识,可查看此博客:http://www.cnblogs.com/chengmo/archive/2010/10/17/1853344.html



接下来我们看下ansilbe自的替换模块。

二、lineinfile模块

ansible-doc帮助信息给我们的示例如下:

- lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=enforcing 行替换
- lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel" 行删除
- lineinfile: dest=/etc/hosts regexp='^127\.0\.0\.1' line='127.0.0.1 localhost' owner=root group=root mode=0644
- lineinfile: dest=/etc/httpd/conf/httpd.conf regexp="^Listen " insertafter="^#Listen " line="Listen 8080" 将以?#Listen?开头行的下面的?以Listen开头的行换成
- lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
# Add a line to a file if it does not exist, without passing regexp
- lineinfile: dest=/tmp/testfile line="192.168.1.99 foo.lab.net foo"
# Fully quoted because of the ': ' on the line. See the Gotchas in the YAML docs.
- lineinfile: "dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL'"
- lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\1Xms${xms}m\3' backrefs=yes
# Validate the sudoers file before saving
- lineinfile: dest=/etc/sudoers state=present regexp='^%ADMIN ALL\=' line='%ADMIN ALL=(ALL) NOPASSWD:ALL' validate='visudo -cf %s'

三、replace模块

该模块有点类似于sed命令,主要也是基于正则进行匹配和替换,如下:

- replace: dest=/etc/hosts regexp='(\s+)old\.host\.name(\s+.*)?$' replace='\1new.host.name\2' backup=yes
- replace: dest=/home/jdoe/.ssh/known_hosts regexp='^old\.host\.name[^\n]*\n' owner=jdoe group=jdoe mode=644
- replace: dest=/etc/apache/ports regexp='^(NameVirtualHost|Listen)\s+80\s*$' replace='\1 127.0.0.1:8080' validate='/usr/sbin/apache2ctl -f %s -t'

四、原来的问题

回到原来的问题,使用ansible安装salt-minion涉及到的替换问题,这里用的playbook最后的修改结果如下:

- name: Fetch configuration from all testservers ,code from www.361way.com
hosts: all
vars:
ID: "id:"
masterip: "master: 10.211.95.232"
tasks:
- name: copy migu repo to hosts
copy: src=./file/migu_rhel7.repo dest=/etc/yum.repos.d/migumirror.repo
- name: install salt repo
yum: name=https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm state=present
- name: install salt minion
yum: name=salt-minion state=latest
- name: set the salt master ip
shell: echo {{ masterip }} >>/etc/salt/minion
- name: Get config
#shell: sed -i '/^#id:/a\id: {{ ansible_ens192.ipv4.address }}' /etc/salt/minion
lineinfile: dest=/etc/salt/minion regexp="^#id" line="{{ ID }} {{ inventory_hostname }}"
- name: enable and start minion
shell: "systemctl enable salt-minion.service && systemctl start salt-minion.service"
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值