英文:
How to store Ansible 'stdout_lines' output in a dictionary?
问题
我有以下的Ansible代码片段,用于打印进程的PID和名称。
- name: 获取所有运行中的进程
shell:
cmd: pgrep -a run.sh
register: _get_pid_and_name
- name: 打印PID详细信息
debug:
msg: "{{ _get_pid_and_name.stdout }}"
上述任务以以下格式输出结果。
"msg": [
1234223 /bin/ksh ./run.sh -f -i 1
4356223 /bin/ksh ./run.sh -f -i 2
887455 /bin/ksh ./run.sh -f -i 3
9934534 /bin/ksh ./run.sh -f -i 4
3245764 /bin/ksh ./run.sh -f -i 5
]
我需要从上述输出中提取PID和名称。
英文:
I have below Ansible snippet that print PIDs and name of process.
- name: Get all running processes
shell:
cmd: pgrep -a run.sh
register: _get_pid_and_name
- name: Print PID details
debug:
msg: "{{ _get_pid_and_name.stdout }}"
Above task prints output in below format
"msg": [
1234223 /bin/ksh ./run.sh -f -i 1
4356223 /bin/ksh ./run.sh -f -i 2
887455 /bin/ksh ./run.sh -f -i 3
9934534 /bin/ksh ./run.sh -f -i 4
3245764 /bin/ksh ./run.sh -f -i 5
]
I need to extract PID and name from the above output.
答案1
得分: 1
创建以下用于测试的脚本
shell> cat run.sh
#!/bin/sh
cat << EOM
1234223 /bin/ksh ./run.sh -f -i 1
4356223 /bin/ksh ./run.sh -f -i 2
887455 /bin/ksh ./run.sh -f -i 3
9934534 /bin/ksh ./run.sh -f -i 4
3245764 /bin/ksh ./run.sh -f -i 5
EOM
运行脚本并注册输出以供测试使用
- script: run.sh
register: get_pid_and_name
分割字段
arr: "{{ get_pid_and_name.stdout_lines|map('split') }}"
得到
arr:
- ['1234223', /bin/ksh, ./run.sh, -f, -i, '1']
- ['4356223', /bin/ksh, ./run.sh, -f, -i, '2']
- ['887455', /bin/ksh, ./run.sh, -f, -i, '3']
- ['9934534', /bin/ksh, ./run.sh, -f, -i, '4']
- ['3245764', /bin/ksh, ./run.sh, -f, -i, '5']
创建字典
pid_name: |
{% filter from_yaml %}
{% for i in arr %}
{{ i.0 }}: {{ i.1 }}
{% endfor %}
{% endfilter %}
得到
pid_name:
887455: /bin/ksh
1234223: /bin/ksh
3245764: /bin/ksh
4356223: /bin/ksh
9934534: /bin/ksh
获取 PID 和 name 的列表
pids: "{{ pid_name.keys()|list }}"
names: "{{ pid_name.values()|list }}"
得到
pids: [1234223, 4356223, 887455, 9934534, 3245764]
names: [/bin/ksh, /bin/ksh, /bin/ksh, /bin/ksh, /bin/ksh]
注意:
- 有许多其他选项可以获取这些列表。例如,
pids: "{{ arr|map('first')|map('int')|list }}"
pids: "{{ arr|json_query('map(&[0], @)') }}"
names: "{{ arr|json_query('map(&[1], @)') }}"
- 完整的测试用例示例
- hosts: localhost
vars:
arr: "{{ get_pid_and_name.stdout_lines|map('split') }}"
pid_name: |
{% filter from_yaml %}
{% for i in arr %}
{{ i.0 }}: {{ i.1 }}
{% endfor %}
{% endfilter %}
pids: "{{ pid_name.keys()|list }}"
names: "{{ pid_name.values()|list }}"
tasks:
- script: run.sh
register: get_pid_and_name
- debug:
var: arr|to_yaml
- debug:
var: pid_name
- debug:
var: pids|to_yaml
- debug:
var: names|to_yaml
英文:
Create the below script for testing
shell> cat run.sh
#!/bin/sh
cat << EOM
1234223 /bin/ksh ./run.sh -f -i 1
4356223 /bin/ksh ./run.sh -f -i 2
887455 /bin/ksh ./run.sh -f -i 3
9934534 /bin/ksh ./run.sh -f -i 4
3245764 /bin/ksh ./run.sh -f -i 5
EOM
Run the script and register the output for testing
- script: run.sh
register: get_pid_and_name
Split the fields
arr: "{{ get_pid_and_name.stdout_lines|map('split') }}"
gives
arr:
- ['1234223', /bin/ksh, ./run.sh, -f, -i, '1']
- ['4356223', /bin/ksh, ./run.sh, -f, -i, '2']
- ['887455', /bin/ksh, ./run.sh, -f, -i, '3']
- ['9934534', /bin/ksh, ./run.sh, -f, -i, '4']
- ['3245764', /bin/ksh, ./run.sh, -f, -i, '5']
Create dictionary
pid_name: |
{% filter from_yaml %}
{% for i in arr %}
{{ i.0 }}: {{ i.1 }}
{% endfor %}
{% endfilter %}
gives
pid_name:
887455: /bin/ksh
1234223: /bin/ksh
3245764: /bin/ksh
4356223: /bin/ksh
9934534: /bin/ksh
Get the lists of PID and name
pids: "{{ pid_name.keys()|list }}"
names: "{{ pid_name.values()|list }}"
gives
pids: [1234223, 4356223, 887455, 9934534, 3245764]
names: [/bin/ksh, /bin/ksh, /bin/ksh, /bin/ksh, /bin/ksh]
<hr>
<sup>
Notes:
- There is plenty of other options on how to get the lists. For example,
pids: "{{ arr|map('first')|map('int')|list }}"
pids: "{{ arr|json_query('map(&[0], @)') }}"
names: "{{ arr|json_query('map(&[1], @)') }}"
<hr>
- Example of a complete playbook for testing
- hosts: localhost
vars:
arr: "{{ get_pid_and_name.stdout_lines|map('split') }}"
pid_name: |
{% filter from_yaml %}
{% for i in arr %}
{{ i.0 }}: {{ i.1 }}
{% endfor %}
{% endfilter %}
pids: "{{ pid_name.keys()|list }}"
names: "{{ pid_name.values()|list }}"
tasks:
- script: run.sh
register: get_pid_and_name
- debug:
var: arr|to_yaml
- debug:
var: pid_name
- debug:
var: pids|to_yaml
- debug:
var: names|to_yaml
</sup>
答案2
得分: 0
我需要从上述输出中提取PID和名称。
由于您已经知道进程的名称,并且您只想查找它,因此名称已知,您只需要提取PID。
对于更通用的如何拆分stdout_lines
并将其转换为字典,您可以直接使用这里已经提供的答案。
另一种方法是使用jc
过滤器 - 将许多Shell命令和文件类型的输出转换为JSON,也许还可以列出仅进程的PIDs。
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: 从链接获取详细信息
ansible.builtin.command: ps -C {{ process }} -o pid=
register: result
changed_when: false
- name: 将命令的结果转换为JSON
ansible.builtin.debug:
msg: "{{ result.stdout | community.general.jc('ps') }}"
请注意,community.general.jc
有其自己的要求,需要在解决之前解决。此外,需要指定解析器。由于缺乏测试环境,我尚未测试ps
或pgrep
命令。
更多类似的文档和问题答案
英文:
> I need to extract PID and name from the above output.
Since you are already know the name of the process and since you are looking it up exclusively, the name is already know and you would need to extract the PIDs only.
For a more generic How to split the stdout_lines
and convert it into a dictionary you could just go with the already given answer here.
An other approach could be to use the jc
filter – Convert output of many shell commands and file-types to JSON maybe together with listing the PIDs of the process only.
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Get detailed information from links
ansible.builtin.command: ps -C {{ process }} -o pid=
register: result
changed_when: false
- name: Convert command's result to JSON
ansible.builtin.debug:
msg: "{{ result.stdout | community.general.jc('ps') }}"
<sub>... not fully tested yet</sub>
Please take note that community.general.jc
has it's own requirements which needs to resolved before. Furthermore, it will be necessary to specifiy the Parser. Because of the lack of testing environment, I haven't tested for the ps
or pgrep
command yet.
Further Documentation Similar Q&A
答案3
得分: 0
尝试使用 pgrep -l run.sh
-l 仅列出进程ID和进程名称
您最终对字典的处理将有助于确定最佳行动方案。
英文:
Try using pgrep -l run.sh
-l lists only the pid and the process name
What you end up doing with the dictionary would help determine the best course of action.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论