ERROR! failed at splitting arguments, either an unbalanced jinja2 block or quotes:

Viewed 10900

I have a script that works in a bash shell. I put it in Ansible and it causes the playbook to have an exception.

- name: add mnt to ignore_filesystems
  shell: |
    grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}' | egrep '\^\\/mnt\*'
    if [ $? -eq 0 ]; then
        echo 'do nothing';
     else
        echo 'no';
        items=$(grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}')
        if [ ${#items} -gt 1 ]; then
            echo 'making the change'
            sed -ie  '/ignore_filesystem/ s~$~|^\\/mnt*~' {{ cdm_path }}
        else
            echo 'making the change'
            sed -ie '/ignore_filesystem/ s~ignore_filesystem = *~ignore_filesystem = ^\\/mnt*~' {{ cdm_path }}
        fi
    fi
  register: ignore_filesystems
  changed_when: '"making the change" in ignore_filesystems.stdout'

I am getting the following message when trying to execute the playbook:

ERROR! failed at splitting arguments, either an unbalanced jinja2 block or quotes: grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}' | egrep '\^\\/mnt\*'
if [ $? -eq 0 ]; then
    echo 'do nothing';
else
    echo 'no';
    items=$(grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}')
    if [ ${#items} -gt 1 ]; then
        echo 'making the change'
        sed -ie  '/ignore_filesystem/ s~$~|^\\/mnt*~' {{ cdm_path }}
    else
        echo 'making the change'
        sed -ie '/ignore_filesystem/ s~ignore_filesystem = *~ignore_filesystem = ^\\/mnt*~' {{ cdm_path }}
    fi
fi

The error appears to have been in '/home/username/provisioning/provisioning/edit_nimbus.yml': 
line 179, column 5, but may be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


  - name: add mnt to ignore_filesystems
    ^ here

Any thoughts on why this might be failing?

=========================================================================

UPDATE:

Tried > as well as | and made all lines the same indentation level. Still the same error

  - name: add mnt to ignore_filesystems
    shell: |
      grep 'ignore_filesystem' {{ cdm_path }}| awk -F'=' '{print $2}' | egrep '\^\\/mnt\*';
      if [ $? -eq 0 ]; then
      echo 'do nothing';
      else
      echo 'no';
      items=$(grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}');
      if [ ${#items} -gt 1 ]; then
      echo 'making the change';
      sed -ie  '/ignore_filesystem/ s~$~|^\\/mnt*~' {{ cdm_path }};
      else
      echo 'making the change';
      sed -ie '/ignore_filesystem/ s~ignore_filesystem = *~ignore_filesystem = ^\\/mnt*~' {{ cdm_path }};
      fi;
      fi
register: ignore_filesystems
changed_when: '"making the change" in ignore_filesystems.stdout'
2 Answers

So this turned out to not be a problem with indentation but with the way ${#items} is interpreted. I was able to get this working with the following code:

- name: add mnt to ignore_filesystems
  shell: |
    grep 'ignore_filesystem' {{ cdm_path }}  | awk -F'=' '{print $2}' | egrep '\^\\/mnt\*';
    if [ $? -eq 0 ]; then
        echo 'do nothing';
    else
        echo 'no';
        items=$(sudo grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}');
        len=$(echo -n $items | wc -m)
        if [ ${len} -gt 1 ]; then
            echo 'making the change';
            echo 'appending...';
            sed -ie  '/ignore_filesystem/ s~$~|^\\/mnt*~' {{ cdm_path }};
        else
            echo 'making the change';
            echo 'replacing';
            sudo sed -ie '/ignore_filesystem/ s~ignore_filesystem = *~ignore_filesystem = ^\\/mnt*~' {{ cdm_path }};
        fi
    fi
  register: ignore_filesystems
  changed_when: '"making the change" in ignore_filesystems.stdout'

This is because the ${#items}, which is used for strings length calculation, is interpreted as jinja2 comment.

{# #} is used for comment in jinja2.

To address this problem, just replace {# with {{ "{" }}{{ "#" }}.

Some blogs say it could be replaced with {{ "{#" }}, or surround shell script with {% raw %} and {% endraw %}, but they didn't work in my tests.

- name: add mnt to ignore_filesystems
  shell: |
    grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}' | egrep '\^\\/mnt\*'
    if [ $? -eq 0 ]; then
        echo 'do nothing';
     else
        echo 'no';
        items=$(grep ignore_filesystem {{ cdm_path }} | awk -F'=' '{print $2}')
        if [ ${{ "{" }}{{ "#" }}items} -gt 1 ]; then
            echo 'making the change'
            sed -ie  '/ignore_filesystem/ s~$~|^\\/mnt*~' {{ cdm_path }}
        else
            echo 'making the change'
            sed -ie '/ignore_filesystem/ s~ignore_filesystem = *~ignore_filesystem = ^\\/mnt*~' {{ cdm_path }}
        fi
    fi
  register: ignore_filesystems
  changed_when: '"making the change" in ignore_filesystems.stdout'
Related