1

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.

U880D
  • 8,601
  • 6
  • 24
  • 40
Sam
  • 97
  • 1
  • 10

3 Answers3

1

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]

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], @)') }}"

  • 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
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
0

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') }}"

... not fully tested yet

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

U880D
  • 8,601
  • 6
  • 24
  • 40
0

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.

b08x
  • 1
  • 1