# Get command error output

**URL:** <https://forum.ansible.com/t/get-command-error-output/4274>\
**Category:** Get Help\
**Created:** [March 8, 2024, 3:08pm UTC](https://forum.ansible.com/t/get-command-error-output/4274 "2024-03-08T15:08:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![codi639](https://avatars.discourse-cdn.com/v4/letter/c/ba9def/32.png) [@codi639](https://forum.ansible.com/u/codi639)\
**Post date:** [March 8, 2024, 3:08pm UTC](https://forum.ansible.com/t/get-command-error-output/4274/1 "2024-03-08T15:08:49Z")

</div>

Hello guys,

I’m trying to manually configure the SSL certificate for the API of my proxmox servers.  
Since I had a lot of error, I find a way using the command `openssl s_client -connect` which returns me a very big output **and** the certificate I need.  
[I made a topic for it.](https://community.influxdata.com/t/failed-to-verify-tls-certificate-with-telegraf/33370)

I just need Ansible to get the output of the command on a file, using some REGEX I could get the SSL certificate and update my `ca-certificates.crt` file.

There’s the Playbook I’ve tried:

```yaml
- name: Fetch certificate from output
  hosts: PROXMOX
  become: true
  tasks:
    - name: Run command to fetch certificate
      ansible.builtin.command: "openssl s_client -connect 172.16.20.11:8006"
      register: certificate_output
      changed_when: true # With and without this option, also tried a "ignore_errors: true"

    - name: Extract certificate content
      ansible.builtin.set_fact:
        certificate_content: "{{ certificate_output.stdout | regex_search('(?<=-----BEGIN CERTIFICATE-----)(.*?)(?=-----END CERTIFICATE-----)', multiline=True) | first }}"

    - name: Save certificate content to file
      ansible.builtin.copy:
        content: "{{ certificate_content }}"
        dest: /usr/local/share/ca-certificates/lets-encrypt.crt
        owner: root
        group: root
        mode: '0644'

```

I can provide you the output, but as I said, it is **VERY** long…  
This is the beginning of the error when running the playbook:

```auto
TASK [Run command to fetch certificate] ********************************************************************************************************************************************************************
fatal: [172.16.20.11]: FAILED! => {"changed": true, "cmd": ["openssl", "s_client", "-connect", "172.16.20.11:8006"], "delta": "0:00:05.073686", "end": "2024-03-08 15:53:12.865630", "msg": "non-zero return code", "rc": 1, "start": "2024-03-08 15:53:07.791944", "stderr":

```

Regards

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [March 8, 2024, 4:48pm UTC](https://forum.ansible.com/t/get-command-error-output/4274/2 "2024-03-08T16:48:08Z")

</div>

It may be long, but it will contain information necessary to further diagnose what’s wrong. As it is, all we know is the `openssl s_client` command returned a non-zero return code.

The way I typically get a certificate from a server would look like this ( ~~slightly untested~~ tested!):

```yaml
- name: Run openssl pipeline to fetch certificate
  ansible.builtin.shell: |
    set -o pipefail
    echo | openssl s_client -connect 172.16.20.11:8006 | openssl x509
  register: certificate_output
  when: true # because we always want to run it
  changed_when: false # because it doesn't change anything

```

You can then skip the set\_fact, because `certificate_output.stdout` will only contain the certificate in the format you need. Use that instead of `certificate_content` in your `copy` task.

However, whatever is currently breaking your `command:` task may well break the above `shell:` task, so we may need to see that long output in any case.

---

<div class="post-metadata">

**Author:** ![codi639](https://avatars.discourse-cdn.com/v4/letter/c/ba9def/32.png) [@codi639](https://forum.ansible.com/u/codi639)\
**Post date:** [March 11, 2024, 8:11am UTC](https://forum.ansible.com/t/get-command-error-output/4274/3 "2024-03-11T08:11:06Z")

</div>

Hello,

Thank you 🙂, I don’t know why but the problem seams to be solved by using the `ansible.builtin.shell` instead of the `ansible.builtin.command`.  
Also, my shell seams to not support the `pipefail` option:

```auto
"stderr": "/bin/sh: 1: set: Illegal option -o pipefail",
    "stderr_lines": [
        "/bin/sh: 1: set: Illegal option -o pipefail"
    ],

```

there’s my playbook:

```yaml
- name: Run command to fetch certificate
  ansible.builtin.shell: |
    echo | openssl s_client -connect 172.16.20.11:8006 | openssl x509
  register: certificate_output
  when: true
  changed_when: false

- name: Save certificate content to file
  ansible.builtin.copy:
    content: "{{ certificate_output }}"
    dest: /usr/local/share/ca-certificates/lets-encrypt.crt
    owner: root
    group: root
    mode: '0644'

```

Regards

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [March 11, 2024, 2:13pm UTC](https://forum.ansible.com/t/get-command-error-output/4274/4 "2024-03-11T14:13:49Z")

</div>

WRT the `pipefail` issue: Older `bash` (like 4.2.46; I don’t know what version this changed) doesn’t support `pipefail` when run as `/bin/sh`. Later versions of bash will support `set -o pipefail` even when invoked as `sh`. On many systems, `sh` is a symbolic link to `bash`, so even though `ansible.builtin.shell` is invoking `/bin/sh`, it’s really `bash` underneath trying to emulate the POSIX shell `sh`.

Although `ansible.builtin.shell` uses `/bin/sh` by default. You can make it run `/bin/bash` instead like below, so you can still set the `pipefail` option on systems with an older `bash`:

```auto
- name: Run /bin/bash instead of /bin/sh
  ansible.builtin.shell: |
    set -o pipefail
    echo $BASH_VERSION
  args:
    executable: /bin/bash

```

---

<div class="post-metadata">

**Author:** ![codi639](https://avatars.discourse-cdn.com/v4/letter/c/ba9def/32.png) [@codi639](https://forum.ansible.com/u/codi639)\
**Post date:** [March 11, 2024, 2:29pm UTC](https://forum.ansible.com/t/get-command-error-output/4274/5 "2024-03-11T14:29:38Z")

</div>

Hello,

Well, even if I saw a way to change the executable I did not try, what I was doing when needed was only something like:

```yaml
- name: some command with bash
      ansible.builtin.command: "/usr/sbin/[the_command]"

```

I just tried by changing the executable and it worked, thank you.

Just to let you know:

```bash
echo $BASH_VERSION
5.2.15(1)-release

```

So I really don’t know why my system don’t want the set pipefail option haha…

Regards

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [April 10, 2024, 2:29pm UTC](https://forum.ansible.com/t/get-command-error-output/4274/6 "2024-04-10T14:29:42Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
