ansible字符串处理(一)
[root@node-1 test]# ansible-playbook hba_card_check.yml
PLAY [compute[0]] *******************************************************************************************************
Tuesday 12 March 2019 08:50:44 +0800 (0:00:00.097) 0:00:00.097 *********
TASK [get hba hosts] ************************************************************************************************************
ok: [172.23.2.9]
Tuesday 12 March 2019 08:50:45 +0800 (0:00:00.425) 0:00:00.522 *********
TASK [set_fact] *******************************************************************************************************************
ok: [172.23.2.9]
Tuesday 12 March 2019 08:50:45 +0800 (0:00:00.112) 0:00:00.635 *********
TASK [debug] *********************************************************************************************************************
ok: [172.23.2.9] => {
"hba_hosts.stdout_lines": [
"/sys/class/fc_host/host11",
"/sys/class/fc_host/host12"
]
}
Tuesday 12 March 2019 08:50:45 +0800 (0:00:00.120) 0:00:00.756 *********
TASK [get hba card state] *********************************************************************************************************
changed: [172.23.2.9]
Tuesday 12 March 2019 08:50:45 +0800 (0:00:00.307) 0:00:01.064 *********
TASK [debug] ***********************************************************************************************************************
ok: [172.23.2.9] => {
"port_state.stdout_lines": [
"[u'', u'sys', u'class', u'fc_host', u'host11'] Online",
"[u'', u'sys', u'class', u'fc_host', u'host12'] Online"
]
}
PLAY RECAP ************************************************************************************************************************
172.23.2.9 : ok=5 changed=1 unreachable=0 failed=0
上边是完整的输出。
代码如下:
---
- hosts: compute[0]
gather_facts: false
tasks:
- name: get hba hosts
shell: ls -d /sys/class/fc_host/host*
register: hba_hosts
failed_when: false
changed_when: false
- set_fact:
hba_count: "{{hba_hosts.stdout_lines|length}}"
when: hba_hosts.rc == 0
- name: get hba card state
shell: |-
{%- for host in hba_hosts.stdout_lines -%}
echo -n "{{ host.split('/') }} "
cat {{ host }}/port_state;
{%- endfor -%}
register: port_state
- debug: var=port_state.stdout_lines
那么字符传的输出处理在get hba cart state这个task的shell里, 使用了jinja2循环,在echo时,对元素host进行路径字符串(hba_hosts.stdout_lines的元素)分割,想得到路径最右的‘/’后的文件夹名称,也就是shell的basename,然而在playbook中,jinja2获取的变量是utf-8编码,而python2.7和shell都是ascii编码,所以此时要得到没有u‘’的字符串需要对这个元素host进行编码,使用.encode()方法(python2默认编码ascii),则可以去掉u'',得到我们想要的结果.
echo -n "{{ host.encode().split('/') }} "
输出即为如下:
TASK [debug] *******************************************************************************************************************
ok: [172.23.2.9] => {
"port_state.stdout_lines": [
"['', 'sys', 'class', 'fc_host', 'host11'] Online",
"['', 'sys', 'class', 'fc_host', 'host12'] Online"
]
}
然而我要获取hosts11 Online和host12 Online的列表,则需使用jinja2的last过滤器获取该值
echo -n "{{ host.encode().split('/') }}|last "
输出如下:
ok: [172.23.2.9] => {
"port_state.stdout_lines": [
"host11 Online",
"host12 Online"
]
}
然而,在大规模的环境里,系统信息的获取时,个人以为shell效率要高于python的,故此处有shell方法:
{%- for host in hba_hosts.stdout_lines -%}
host={{host}}
echo -n "${host##*/} " # echo -n "$(basename $host) "
#echo -n "{{ host.encode().split('/')|last}} "
cat {{ host }}/port_state;
{%- endfor -%}