使用带方括号的文件名时,带有 'creates' 的命令不是幂等的

Command with 'creates' is not idempotent when using filenames with square brackets

我有一个创建多个文件的任务,如果它们不存在的话。它一直有效,直到文件名被用作包含一对方括号的项目。我尝试使用反斜杠和 {% raw %} 标签进行转义,但它不起作用。

测试剧本:

---
- name: Test playbook
  hosts: localhost
  gather_facts: no

  tasks:
  - name: Testfile
    ansible.builtin.command:
      cmd: 'touch ~/{{ item }}'
    args:
      creates: "~/{{ item }}"
    with_items:
      - 'test1.txt' # works
      - 'tes[t2.txt' # works
      - 'test3].txt' # works
      - 'tes[t4].txt' # DOESNT WORK

第一个运行:

changed: [localhost] => (item=test1.txt)
changed: [localhost] => (item=tes[t2.txt)
changed: [localhost] => (item=test3].txt)
changed: [localhost] => (item=tes[t4].txt)

连续运行秒:

ok: [localhost] => (item=test1.txt)
ok: [localhost] => (item=tes[t2.txt)
ok: [localhost] => (item=test3].txt)
changed: [localhost] => (item=tes[t4].txt)

文件夹内容:

ls ~/tes*
'/home/user/tes[t2.txt'  '/home/user/tes[t4].txt'   /home/user/test1.txt   /home/user/test3].txt

环境:

这是一个错误,还是有什么方法可以转义字符,使任务完全幂等?

问题是由于 creates can handle glob syntax (highlighted by @Jack). In glob syntax [ has a special meaning and need to be escaped. I did manage to do it only manually by escaping the [ through this Jinja2 filter {{ item|replace('[', '[[]') }}. I did not found an equivalent convenient filter equivalent to Python glob.escape。但是它有效!

- name: Test playbook
  hosts: localhost
  gather_facts: no

  tasks:
  - name: Testfile
    ansible.builtin.command:
      cmd: "touch ~/{{ item }}"
    args:
      creates: "~/{{ item|replace('[', '[[]') }}"
    with_items:
      - 'test1.txt' # works
      - 'tes[t2.txt' # works
      - 'test3].txt' # works
      - 'tes[t4].txt' # DOESNT WORK

进一步阅读 glob 转义 -> glob and bracket characters ('[]').