1

I use the ansible.builtin.lineinfile module to modify a PHP-FPM pool configuration file. How should I quote the square brackets (annot.: or other special characters) in a value of a variable for the regexp parameter?

Without quoting the square brackets are interpreted as bracket expression - a list of characters to be matching. Without Ansible I would use sed to add a backslash.

The following example is for a Debian default pool conf file.

- name: Change PHP-FPM pool parameters
  become: true
  ansible.builtin.lineinfile:
    path: "/etc/php/{{ php_fpm_version }}/fpm/pool.d/www.conf"
    regexp: "^;?{{ item.para }} ="
    line: '{{ item.para }} = {{ item.value }}'
  loop: "{{ php_fpm_pool_parameters }}"
  vars:
    php_fpm_pool_parameters:
    - para: 'pm.max_spare_servers'
      value: '7'
    - para: 'pm.max_requests'
      value: '500'
    - para: 'env[PATH]'
      value: '/usr/bin:/bin'
    - para: 'php_admin_value[memory_limit]'
      value: '4096M'
    - para: 'php_admin_value[max_input_time]'
      value: '600'
4
  • Since you are writing already in line: '{{ item.para }}' you can also write in regexp: "^;?{{ item.para }} =". There should be no need for an other syntax. Documentation: Referencing nested variables.
    – U880D
    Commented Oct 15, 2022 at 8:23
  • Sure, but this does not solve the problem. The square brackets in the three last list items are interpreted as "bracket expression", which means as P, A, T or H in the first case.
    – togo
    Commented Oct 15, 2022 at 18:59
  • Because of the comment "Sure" and then the opposite "does not solve the problem", can you provide a more detailed description?
    – U880D
    Commented Oct 16, 2022 at 5:38
  • To avoid misunderstandings, I have changed the line. The {{ item['para'] }} was an attempt to solve the problem by avoiding conflicts like described here: Referencing key:value dictionary variables The problem is that regex is supposed to search for [PATH], including the square bracket, and not P, A, T, or H.
    – togo
    Commented Oct 16, 2022 at 21:23

1 Answer 1

5

You need to escape the regex special characters in your string so that they are taken literally. FYI, escaping is not different in ansible than outside (i.e. you add the escape char which is \).

Fortunately, there is a regex_escape filter made just for that.

The following (untested) should suit your needs. Note: for extra security I marked the space preceding the = sign as optional and extended the regexp to match the entire line.

- name: Change PHP-FPM pool parameters
  become: true
  ansible.builtin.lineinfile:
    path: "/etc/php/{{ php_fpm_version }}/fpm/pool.d/www.conf"
    regexp: "^;?{{ item.para | regex_escape }} ?=.*$"
    line: '{{ item.para }} = {{ item.value }}'
  loop: "{{ php_fpm_pool_parameters }}"
  vars:
    php_fpm_pool_parameters:
    - para: 'pm.max_spare_servers'
      value: '7'
    - para: 'pm.max_requests'
      value: '500'
    - para: 'env[PATH]'
      value: '/usr/bin:/bin'
    - para: 'php_admin_value[memory_limit]'
      value: '4096M'
    - para: 'php_admin_value[max_input_time]'
      value: '600'
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .