由于变量格式问题,无法在 Ansible 中获取现有目录的统计信息

Unable to get stat of existing directory in Ansible due to variable formatting issue

提问人:Ashar 提问时间:11/13/2023 最后编辑:U880DAshar 更新时间:11/13/2023 访问量:88

问:

我正在尝试将第一个目录的所有者传递给 Ansible 变量。source_files

我们无法控制 Ansible 变量的内容,因为它是通过一些 OLAM API 构建的。我为这个例子硬编码了它。source_files

变量的两个文件都存在,如下所示:source_files

[wluser@mylocalhost ~]$ ls -ltr '/tmp/my  private.txt' /tmp/files.sh  
-rw-r--r-- 1 wluser mygrp 0 Nov 12 21:52 /tmp/files.sh    
-rw-r--r-- 1 wluser mygrp 0 Nov 12 21:52 /tmp/my  private.txt

剧本 [wluser@mylocalhost ~]$ cat formatstring.yml

---
- name: "Play 1-Find the details here"

  hosts: localhost
  any_errors_fatal: True
  gather_facts: no

  tasks:

   - name: Set source_files variable
     set_fact:
       source_files: "'/tmp/my  private.txt','/tmp/files.sh'"
 
   - name: Print source_files
     debug:
       msg: "source_files: {{ source_files }}"
     
   - name: Loop Print source_files
     debug:
       msg: "{{ item }}"
     loop: "{{ source_files.split(',') }}"

   - name: Single Print source_files
     debug:
       msg: "{{ source_files.split(',')[0] }}"
   
   - name: Get directory owner
     ansible.builtin.stat:
       path: "{{ tomcat_home_item }}"
     register: dir_stat
     vars:
       tomcat_home_item: "{{ source_files.split(',')[0] | trim }}"

   - name: Store directory owner's UID in a variable
     set_fact:
       owner_uid: "{{ dir_stat.stat.pw_name | default('baduser') }}"

   - debug:
       msg: "Detected user is: {{ owner_uid }}"

   - name: Get directory owner
     ansible.builtin.stat:
       path: "{{ tomcat_home_item | regex_replace('^\\s*'|'\\s*$', '') }}"
     register: dir_stat
     vars:
       tomcat_home_item: "{{ source_files.split(',')[0] | trim }}"

   - name: Store directory owner's UID in a variable
     set_fact:
       owner_uid: "{{ dir_stat.stat.pw_name | default('baduser') }}"
 
   - debug:
       msg: "Detected user is: {{ owner_uid }}"

输出

[wluser@mylocalhost ~]$ ansible-playbook formatstring.yml -vvv
ansible-playbook 2.8.4
  config file = /etc/ansible/ansible.cfg
PLAYBOOK: formatstring.yml ****************************************************************************************************
1 plays in formatstring.yml

PLAY [Play 1-Find the details here] *******************************************************************************************
META: ran handlers

TASK [Set source_files variable] **********************************************************************************************
task path: /home/wluser/formatstring.yml:10
Sunday 12 November 2023  22:02:56 -0600 (0:00:00.044)       0:00:00.044 *******
ok: [localhost] => {
    "ansible_facts": {
        "source_files": "'/tmp/my  private.txt','/tmp/files.sh'"
    },
    "changed": false
}

TASK [Print source_files] *****************************************************************************************************
task path: /home/wluser/formatstring.yml:15
Sunday 12 November 2023  22:02:56 -0600 (0:00:00.018)       0:00:00.062 *******
ok: [localhost] => {
    "msg": "source_files: '/tmp/my  private.txt','/tmp/files.sh'"
}

TASK [Loop Print source_files] ************************************************************************************************
task path: /home/wluser/formatstring.yml:19
Sunday 12 November 2023  22:02:56 -0600 (0:00:00.017)       0:00:00.080 *******
ok: [localhost] => (item='/tmp/my  private.txt') => {
    "msg": "'/tmp/my  private.txt'"
}
ok: [localhost] => (item='/tmp/files.sh') => {
    "msg": "'/tmp/files.sh'"
}

TASK [Single Print source_files] **********************************************************************************************
task path: /home/wluser/formatstring.yml:24
Sunday 12 November 2023  22:02:56 -0600 (0:00:00.033)       0:00:00.114 *******
ok: [localhost] => {
    "msg": "'/tmp/my  private.txt'"
}

TASK [Get directory owner] ****************************************************************************************************
task path: /home/wluser/formatstring.yml:29
Sunday 12 November 2023  22:02:56 -0600 (0:00:00.023)       0:00:00.137 *******
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: wluser
ok: [localhost] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "checksum_algorithm": "sha1",
            "follow": false,
            "get_attributes": true,
            "get_checksum": true,
            "get_md5": null,
            "get_mime": true,
            "path": "'/tmp/my  private.txt'"
        }
    },
    "stat": {
        "exists": false
    }
}

TASK [Store directory owner's UID in a variable] ******************************************************************************
task path: /home/wluser/formatstring.yml:36
Sunday 12 November 2023  22:02:57 -0600 (0:00:00.352)       0:00:00.489 *******
ok: [localhost] => {
    "ansible_facts": {
        "owner_uid": "baduser"
    },
    "changed": false
}

TASK [debug] ******************************************************************************************************************
task path: /home/wluser/formatstring.yml:40
Sunday 12 November 2023  22:02:57 -0600 (0:00:00.020)       0:00:00.510 *******
ok: [localhost] => {
    "msg": "Detected user is: baduser"
}

TASK [Get directory owner] ****************************************************************************************************
task path: /home/wluser/formatstring.yml:43
Sunday 12 November 2023  22:02:57 -0600 (0:00:00.019)       0:00:00.529 *******
fatal: [localhost]: FAILED! => {
    "msg": "template error while templating string: expected token 'name', got 'string'. String: {{ tomcat_home_item | regex_replace('^\\\\s*'|'\\\\s*$', '') }}"
}

NO MORE HOSTS LEFT ************************************************************************************************************
PLAY RECAP ********************************************************************************************************************
localhost                  : ok=7    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

如您所见,由于变量的引用/格式问题,我得到的不是正确的用户。baduserwlusersource_files

然后我试图删除引号,但这给了我运行时错误。

您能否建议我如何将统计信息获取到文件中,考虑到最初在 playbook 中提到的source_files格式无法更改。

ansible 运行时 - 错误 参数 - 传递 字符串格式 stat

评论

0赞 U880D 11/13/2023
"我们无法控制 Ansible 变量source_files因为它是通过一些 OLAM API 构建的。你能展示一下真实内容吗?使用当前提供的信息,无法为我重现问题。source_files
0赞 Ashar 11/13/2023
@U880D您可以按原样运行代码并能够使用 ansible 2.7.8 重现错误,我有set_fact sources_files,因为我的游戏打印了,所以没有区别
0赞 U880D 11/13/2023
不,这就是我问的原因。您正在任务中设置变量内容。对我来说,在这个阶段还不清楚这是否是OLAM API的输出。set_fact
0赞 Ashar 11/13/2023
@U880D我复制了 Olam 的输出,但他们的打印方式并将其用作此测试用例的set_fact,这是可重现的。我制作了一个视频,我只需从这篇关于堆栈溢出的帖子中复制粘贴并运行播放。这里: youtu.be/pA1xo5Vu4Tg?feature=shared
0赞 U880D 11/13/2023
我不明白制作视频的好处,如果你通过编辑最初的问题和描述来展示一些东西是复制和粘贴的,而不是复制和粘贴它,包括你的OLAM API的确切输出是什么以及你是如何收集它的细节。

答:

1赞 U880D 11/13/2023 #1

考虑到source_files的格式,我怎样才能获得文件的统计信息

假设命令的输出是正确的,以及 的内容是正确的。对于文件ls -ltrsource_files

~/test$ ls -ltr 'test file' 'test path' 'test path/test file'
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test file
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test path/test file

test path:
total 0
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test file

最小的示例 playbook


```---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    FILE: 'test file'
    PATH: 'test path'

  tasks:

  - set_fact:
      SOURCE_FILES: "'test file','test path/test file'"

  - stat:
      path: 'test file'
    register: result

  - debug:
      msg: "{{ result.stat.path }}"

  - stat:
      path: "{{ FILE }}"
    register: result

  - debug:
      msg: "{{ result.stat.path }}"

  - stat:
      path: "{{ PATH }}/{{ FILE }}"
    register: result

  - debug:
      msg: "{{ result.stat.path }}"

  - debug:
      msg:
        - "Content: {{ SOURCE_FILES }}"
        - "Type: {{ SOURCE_FILES | type_debug }}"
        - "List of files: {{ SOURCE_FILES | split(',') }}"

  - stat:
      path: "{{ SOURCE_FILES | split(',') | first | replace(\"'\",'') }}"
    register: result

  - debug:
      msg: "{{ result.stat.path }}"

  - stat:
      path: "{{ SOURCE_FILES | split(',') | last | replace(\"'\",'') }}"
    register: result

  - debug:
      msg: "{{ result.stat.path }}"

将导致

TASK [stat] ******************************************************
ok: [localhost]

TASK [debug] *****************************************************
ok: [localhost] =>
  msg: test file

TASK [stat] ******************************************************
ok: [localhost]

TASK [debug] *****************************************************
ok: [localhost] =>
  msg: test file

TASK [stat] ******************************************************
ok: [localhost]

TASK [debug] *****************************************************
ok: [localhost] =>
  msg: test path/test file

TASK [debug] *****************************************************
ok: [localhost] =>
  msg:
  - 'Content: ''test file'',''test path/test file'''
  - 'Type: AnsibleUnicode'
  - 'List of files: [u"''test file''", u"''test path/test file''"]'

TASK [stat] ******************************************************
ok: [localhost]

TASK [debug] *****************************************************
ok: [localhost] =>
  msg: test file

TASK [stat] ******************************************************
ok: [localhost]

TASK [debug] *****************************************************
ok: [localhost] =>
  msg: test path/test file

如果内容是逗号分隔值 (CSV) 字符串,其中包含显式引号值和引号字符 (...annot:它使非 RFC 符合),以再次从中制作文件名列表source_filessingle quote (')

  • 在分隔符逗号 () 上拆分 via,split(',')
  • 通过以下方式删除所有值的显式引号字符single quote (')replace(\"'\",'')

请不要认为文件不能再包含单引号,因为这会再次遇到错误。在示例中,它会失败

~/test$ touch "andrew's.file"
~/test$ ls -al and*
-rw-r--r--. 1 ansible_user users 0 Nov 13 09:30 andrew's.file
-rw-r--r--. 1 ansible_user users 0 Nov 13 09:30 and.yml

由于

评论

0赞 Ashar 11/13/2023
我们传递给 Olam 的任何内容都会被双引号括起来,作为参数传递给 ansible,因此将转到 ansible Play as .记住这一点,将空白文件/文件夹路径传递和读取到 ansible play 中更好的方法是什么?好心建议?我想把它们用单引号括起来,这样文件名中的空格就可以保持并用逗号分隔。想获得专家/其他建议以使其成为更好的解决方案吗?请注意,我不控制 OLam,而只是传递从 github actions > olam - > ansible 接收的参数passvar=value one- e passvar="valueone"
0赞 U880D 11/13/2023
"我想把它们括在单引号里,这样文件名中的空格就可以保持并用逗号分隔“,人们可以定义任何对他有用的数据结构,只要在整个处理过程中坚持下去。如果数据结构发生变化,或者在不同的处理步骤中预期不同的结构,通常会出现问题。尤其是在不同的(操作)系统上。