Skip to content

False positive and bad auto --fix for command-instead-of-shell #4386

@wimglenn

Description

@wimglenn
Summary

In this task, if there was a pre-existing crontab it is considered a (non-fatal) failure mode:

- name: Get pre-existing crontab (if any)
  ansible.builtin.shell: "! crontab -l"
  changed_when: false
  register: missing_crontab
  ignore_errors: true # don't stop the rest of the playbook

We invert the return code (i.e. we want rc=0 when there is no existing crontab) using POSIX shell ! operator.

ansible-lint is unhappy and wants the task to use ansible.builtin.command instead of shell:

command-instead-of-shell: Use shell only when shell functionality is required.

The auto-fixer makes a suggestion which doesn't actually work:

- name: Get pre-existing crontab (if any)
  ansible.builtin.command: "! crontab -l"
  changed_when: false
  register: missing_crontab
  ignore_errors: true # don't stop the rest of the playbook

This "fixed" task fails, it appears to be trying to run a program called literally "!":

TASK [Get pre-existing crontab (if any)] ***********************
fatal: [examplehost]: FAILED! => changed=false 
  cmd: '''!'' crontab -l'
  msg: '[Errno 2] No such file or directory: b''!'': b''!'''
  rc: 2
  stderr: ''
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>
...ignoring

Workaround: use ansible.builtin.command: bash -c "! crontab -l"

Issue Type
  • Bug Report
OS / ENVIRONMENT
$ ansible-lint --version
ansible-lint 24.9.2 using ansible-core:2.16.11 ansible-compat:24.9.1 ruamel-yaml:0.18.6 ruamel-yaml-clib:0.2.8
  • ansible installation method: pip
  • ansible-lint installation method: pip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions