可视化的剧本外壳输出

我想使用 ps、 dstat 等命令使用 anable-playbook 快速监视一些主机。ansible命令本身完美地完成了我想要的任务,例如,我会使用:

ansible -m shell -a "ps -eo pcpu,user,args | sort -r -k1 | head -n5"

它可以很好地打印每个主机的所有 std 输出,如下所示:

localhost | success | rc=0 >>
0.0 root     /sbin/init
0.0 root     [kthreadd]
0.0 root     [ksoftirqd/0]
0.0 root     [migration/0]


otherhost | success | rc=0 >>
0.0 root     /sbin/init
0.0 root     [kthreadd]
0.0 root     [ksoftirqd/0]
0.0 root     [migration/0]

然而,这需要我为每一个不是很“可行”的任务保留一堆 shell 脚本,所以我把它放在一个剧本中:

---
-
hosts: all
gather_facts: no
tasks:
- shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5

然后用 -vv运行它,但是输出基本上显示了字典内容和换行并没有像这样打印出来,所以结果就是这样一团糟:

changed: [localhost] => {"changed": true, "cmd": "ps -eo pcpu,user,args | sort -r -k1
head -n5 ", "delta": "0:00:00.015337", "end": "2013-12-13 10:57:25.680708", "rc": 0,
"start": "2013-12-13 10:57:25.665371", "stderr": "", "stdout": "47.3 xxx    Xvnc4 :24
-desktop xxx:24 (xxx) -auth /home/xxx/.Xauthority -geometry 1920x1200\n
....

我还尝试添加 register: var和“ debug”任务来显示 {{ var.stdout }},但结果当然是一样的。

当通过剧本运行命令的 stdout/stderr 时,有没有一种方法可以获得格式很好的输出?我可以想到一些可能的方法(使用 sed 格式化输出?将输出重定向到主机上的文件,然后将该文件返回并回显到屏幕上?)但是以我对 shell/可能性的有限了解,我需要一天的时间才能尝试一下。

226231 次浏览

这是一个可能的开始:

- hosts: all
gather_facts: no
tasks:
- shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5
register: ps


- local_action: command echo item
with_items: ps.stdout_lines

注意: 关于 ps.stdout_lines的文档在这里涵盖: (“注册变量”一章)

扩展一下 Leucos 的回答,你也可以打印一些信息,使用安塞尔的简陋的 debug模块:

- hosts: all
gather_facts: no
tasks:
- shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5
register: ps


# Print the shell task's stdout.
- debug: msg=\{\{ ps.stdout }}


# Print all contents of the shell task's output.
- debug: var=ps

debug模块确实需要一些爱,但目前你能做的最好的就是使用这个:

- hosts: all
gather_facts: no
tasks:
- shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5
register: ps


- debug: var=ps.stdout_lines

它的输出如下:

ok: [host1] => {
"ps.stdout_lines": [
"%CPU USER     COMMAND",
" 1.0 root     /usr/bin/python",
" 0.6 root     sshd: root@notty ",
" 0.2 root     java",
" 0.0 root     sort -r -k1"
]
}
ok: [host2] => {
"ps.stdout_lines": [
"%CPU USER     COMMAND",
" 4.0 root     /usr/bin/python",
" 0.6 root     sshd: root@notty ",
" 0.1 root     java",
" 0.0 root     sort -r -k1"
]
}

也许不相关,如果你想做到这一点只使用可能。但是在我的 .bash_profile中有一个函数,然后运行 _check_machine host1 host2对我来说要容易得多

function _check_machine() {
echo 'hostname,num_physical_procs,cores_per_procs,memory,Gen,RH Release,bios_hp_power_profile,bios_intel_qpi_link_power_management,bios_hp_power_regulator,bios_idle_power_state,bios_memory_speed,'
hostlist=$1
for h in `echo $hostlist | sed 's/ /\n/g'`;
do
echo $h | grep -qE '[a-zA-Z]'
[ $? -ne 0 ] && h=plabb$h
echo -n $h,
ssh root@$h 'grep "^physical id" /proc/cpuinfo | sort -u | wc -l; grep "^cpu cores" /proc/cpuinfo |sort -u | awk "{print \$4}"; awk "{print \$2/1024/1024; exit 0}" /proc/meminfo; /usr/sbin/dmidecode | grep "Product Name"; cat /etc/redhat-release; /etc/facter/bios_facts.sh;' | sed 's/Red at Enterprise Linux Server release //g; s/.*=//g; s/\tProduct Name: ProLiant BL460c //g; s/-//g' | sed 's/Red Hat Enterprise Linux Server release //g; s/.*=//g; s/\tProduct Name: ProLiant BL460c //g; s/-//g' | tr "\n" ","
echo ''
done
}

例如。

$ _machine_info '10 20 1036'
hostname,num_physical_procs,cores_per_procs,memory,Gen,RH Release,bios_hp_power_profile,bios_intel_qpi_link_power_management,bios_hp_power_regulator,bios_idle_power_state,bios_memory_speed,
plabb10,2,4,47.1629,G6,5.11 (Tikanga),Maximum_Performance,Disabled,HP_Static_High_Performance_Mode,No_CStates,1333MHz_Maximum,
plabb20,2,4,47.1229,G6,6.6 (Santiago),Maximum_Performance,Disabled,HP_Static_High_Performance_Mode,No_CStates,1333MHz_Maximum,
plabb1036,2,12,189.12,Gen8,6.6 (Santiago),Custom,Disabled,HP_Static_High_Performance_Mode,No_CStates,1333MHz_Maximum,
$

不用说函数不适合你,你需要适当地更新它。

如果您需要一个特定的退出状态,安赛尔提供了一种方法,通过 回调插件做到这一点。

示例 。如果需要100% 准确的退出状态,这是一个非常好的选项。

如果没有,您总是可以使用 < strong > 调试模块 ,对于这种情况的使用,它是 标准

干杯

我发现使用 一个 href = “ https://github.com/anible/blob/devel/anable/plugins/callback/minial.py”rel = “ nofollow noReferrer”> little stdout_callback与可控制的剧本提供了类似的输出使用特设可控制。

在您的 ansible.cfg 中(注意,我在 OS X 上,因此修改 callback_plugins路径以适应您的安装)

stdout_callback     = minimal
callback_plugins    = /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/plugins/callback

所以像你这样的 ansible-playbook任务

---
-
hosts: example
gather_facts: no
tasks:
- shell: ps -eo pcpu,user,args | sort -r -k1 | head -n5

像 ad-hoc 命令那样提供这样的输出

example | SUCCESS | rc=0 >>
%CPU USER     COMMAND
0.2 root     sshd: root@pts/3
0.1 root     /usr/sbin/CROND -n
0.0 root     [xfs-reclaim/vda]
0.0 root     [xfs_mru_cache]

我正在使用可感知剧本2.2.1.0

ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook /tmp/foo.yml -vvv

使用 STDOUT 的任务将有一个部分:

STDOUT:


What ever was in STDOUT

对我来说,唯一有效的方法(因为 register + with _ item 组合)是这样的:

- name: "download and distribute certs"
shell: "python3 /tmp/bla.py \{\{ item.name }}"
register: python3
with_items: "\{\{ my_list }}"


- debug: msg="\{\{ item.stdout_lines | join("\n") }}"
with_items: "\{\{ python3['results'] }}"

我个人在一个剧本中有几个 shell 或命令调用,并收集输出到不同变量的数据。最后,我总结了所有的信息,并一次性列出如下所示:

- ansible.builtin.shell: "df -h"
register: disk


- ansible.builtin.shell: "free -m"
register: mem

.....

- name: Summarize
local_action: ansible.builtin.debug var=\{\{ item }}
become: no
with_items:
- disk.stdout_lines
- mem.stdout_lines

如果你把它叫做

ANSIBLE_STDOUT_CALLBACK=minimal ansible-playbook getServerInfo.yml

它提供了一个很好的,干净的输出