0

I'm trying to run the below ansible ad-hoc command that runs the "status.sh" script:

ansible host -m script -a '/path/status.sh' -u root -i inventory

The script simply gets the status of a service on the target host as shown below:

service_1=$(ls /etc/systemd/system | grep -e jboss | awk -F ' ' '{print $1}')

if [ ! -z "$service_1" ] //if service exists
then
      systemctl status $service_1
else
      echo "There is No $Service_1 Here !"
fi

I'm getting too much output when running the ad-hoc command, I just want to limit the output to stdout_lines or stdout, Is there a way to do so without creating a particular playbook with debug or any other modules just by adding an option or piping the output to a grep?

  • Because your actual example and use case currently looks like an anti-pattern for Ansible and which should be avoided, can you explain why you are looking for "_... a way to do so without creating a particular playbook with "debug" or any other modules just by adding an option or piping the output to a grep..._"? – U880D Sep 12 '22 at 14:17
  • 1
    [Change the ad-hoc command line stout callback plugin to json](/a/62110058/9401096). Filtering the output with a tool like `jq` is then trivial. – Zeitounator Sep 12 '22 at 22:58
  • Thanks @U880D for your input, I'm just wondering if there is a way to do so, I know that a playbook can be used by registering the output and then printing the wanted part using the "debug" module, I've tried the provided answer and it works. – Mostafa Ramzy Sep 22 '22 at 04:23
  • Thanks @Zeitounator for your input, I'm just wondering if there is a way to do so without using playbooks or any plugins just by using native options, I've tried the provided answer and it works. – Mostafa Ramzy Sep 22 '22 at 04:27

3 Answers3

1

In my point of view, the in the original question tried approach to gather service statuses should be avoided since that example seems to be an anti-pattern for Ansible. However, there are options to fulfill the requirement for a report.

A simpler solution is either

ansible test -m systemd -a 'name=cntlm enabled=true'
test.example.com | SUCCESS => {
    "changed": false,
    "enabled": true,
    "name": "cntlm",
    "status": {
<a lot of output>
    }
}

or

ansible test -m shell -a 'systemctl status cntlm'
test.example.com | CHANGED | rc=0 >>
● cntlm.service - CNTLM HTTP Accelerator For NTLM Secured Proxies Authenticator
   Loaded: loaded (/usr/lib/systemd/system/cntlm.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-09-01 09:00:00 CEST; 1 weeks 4 days ago
 Main PID: 234567 (cntlm)
   CGroup: /system.slice/cntlm.service
           └─234567 /usr/sbin/cntlm -c /etc/cntlm.conf -U cntlm -P /run/cntlm/cntlmd.pid

or almost the requested, after enabling callback plugin for ad hoc commands

ansible test -m shell -a 'systemctl status cntlm'

PLAY [Ansible Ad-Hoc] **************************************************************************************************
Monday 01 September 2022  09:00:00 +0200 (0:00:00.071)       0:00:00.071 ******

TASK [shell] ***********************************************************************************************************
changed: [test.example.com]

PLAY RECAP *************************************************************************************************************
test.example.com  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Monday 01 September 2022  09:00:00 +0200 (0:00:02.171)       0:00:02.243 ******
===============================================================================
shell ----------------------------------------------------------------------------------------------------------- 2.17s
Playbook run took 0 days, 0 hours, 0 minutes, 2 seconds

Config

[defaults]
bin_ansible_callbacks   = True

Further Q&A


Finally, If you are now are interested in customizing the output more, you'll probably need to start Developing plugins and creating your own Callback plugin. The source of lib/ansible/plugins/callback/default.py can be a good start.

U880D
  • 8,601
  • 6
  • 24
  • 40
  • Thanks for your input, This plugin really helps but the request as mentioned was to do so without using playbooks or any plugins just by using native options, I've tried the provided answer and it works. – Mostafa Ramzy Sep 30 '22 at 10:09
1

Is there a way to do so without creating a particular playbook with debug or any other modules just by adding an option or piping the output to a grep?

I'm quite sure my above proposition in comment fulfills your expectation. The only requirement is to have a tool installed on the controller to parse json so that you can pipe Ansible output result in your shell.

For the below example, I use jq which is widely used and available in most Linux distribution repos.

The trick here is to:

  1. enable loading callbacks for ad-hoc commands.
  2. change the stdout callback plugin to use json for ad-hoc commands.

Since you seem to look for a one liner and non "destructive" solution, I used environment variables set directly on the same command line.

Long story short, typing in your shell:

ANSIBLE_LOAD_CALLBACK_PLUGINS=1 \
ANSIBLE_STDOUT_CALLBACK=json \
ansible localhost -a "echo toto" | jq -r ".plays[].tasks[].hosts[].stdout"

gives

toto
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Thanks for your input, This plugin really helps but the request as mentioned was to do so without using playbooks or any plugins just by using native options, I've tried the provided answer and it works. – Mostafa Ramzy Sep 30 '22 at 09:20
  • @MostafaRamzy this solution does not use any playbook and only plugins which are available in a default ansible installation (unless you decided to go through the ansible-core only route in which case it is necessary to install the posix collection). You actually use a stdout plugin anyway when firing an ad-hoc ansible command with the default configuration (i.e. the [default callback plugin](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/default_callback.html#ansible-collections-ansible-builtin-default-callback)) – Zeitounator Sep 30 '22 at 11:46
0

There is no inbuilt option for ansible adoc commands to filter output unless supported by module itself(eg setup module).

If you want to compress output in single line you can use "-o" option.

Only option seems to be work with shell to filter out output. I have come up with below command you can give it a try

ansible test_node1 -m script -a "/root/python/test.sh" | grep "\"stdout\":" | tr -d  ','  | echo -e `awk '{print $2}'`
  • I've tried the suggested way and modified only the last part to limit the output variables as per the required as per below and it works, Thanks. – Mostafa Ramzy Sep 13 '22 at 09:39
  • ansible test_node1 -m script -a "/root/python/test.sh" -u root -i inventory | grep "\"stdout\":" | tr -d ',' | echo -e `awk '{print $1 $2 $3 $4 $12 $16 $17 $18}'` – Mostafa Ramzy Sep 13 '22 at 09:39