读取 JSON 内容为数字时 Ansible 中的错误文件描述符

Bad file descriptor in Ansible when read JSON content is numeric

下面是我的 JSON 文件:

[
  {
    "?xml": {
      "attributes": {
        "encoding": "UTF-8",
        "version": "1.0"
      }
    }
  },
  {
    "domain": [
      {
        "name": "mydom"
      },
      {
        "domain-version": "12.2.1.3.0"
      },
      {
        "server": [
          {
            "name": "AdminServer"
          },
          {
            "ssl": {
              "name": "AdminServer"
            }
          },
          {
            "listen_port": "12400"
          },
          {
            "listen_address": "mydom.host1.bank.com"
          }
        ]
      },
      {
        "server": [
          {
            "name": "myserv1"
          },
          {
            "ssl": [
              {
                "name": "myserv1"
              },
              {
                "login-timeout-millis": "25000"
              }
            ]
          },
          {
            "listen_port": "22421"
          }
        ]
      }
    ]
  }
]

这是从 json

中获取监听端口号的代码
---
  - name: ReadJsonfile
    hosts: localhost
    tasks:
      - name: Display the JSON file content
        shell: "cat this.json"
        register: result

      - name: save the Json data to a Variable as a Fact
        set_fact:
          jsondata: "{{ result.stdout | from_json }}"

      - name: create YML for server name with Listen port
        shell: "echo {{ server.0.name }}_httpport: {{ httpport[0].listen_port }}>>{{ playbook_dir }}/wlsdatadump.yml"
        loop: "{{ jsondata[1].domain }}"
        vars:
          server: "{{ item.server | selectattr('name', 'defined') }}"
          httpport: "{{ item.server | selectattr('listen_port', 'defined') | list }}"
        when: item.server is defined and (item.server | selectattr('listen_port', 'defined')) != []

执行播放时出现以下错误

TASK [create YML for server name with Listen port] ************************************************************
skipping: [localhost] => (item={'name': 'mydom'})
skipping: [localhost] => (item={'domain-version': '12.2.1.3.0'})
failed: [localhost] (item={'server': [{'name': 'AdminServer'}, {'ssl': {'name': 'AdminServer'}}, {'listen_port': '12400'}, {'listen_address': 'mydom.host1.bank.com'}]}) => {"ansible_loop_var": "item", "changed": true, "cmd": "echo AdminServer_httpport: 12400>>/web/aes/admin/playbooks/dump.yml", "delta": "0:00:00.007706", "end": "2022-03-17 04:43:24.665832", "item": {"server": [{"name": "AdminServer"}, {"ssl": {"name": "AdminServer"}}, {"listen_port": "12400"}, {"listen_address": "mydom.host1.bank.com"}]}, "msg": "non-zero return code", "rc": 1, "start": "2022-03-17 04:43:24.658126", "stderr": "/bin/sh: 12400: Bad file descriptor", "stderr_lines": ["/bin/sh: 12400: Bad file descriptor"], "stdout": "", "stdout_lines": []}

如果我将端口号从数字更改为非数字,比如将“12400”更改为“portfirst”,剧本就可以正常工作。

这个问题可能与数据类型有关。

你能建议我如何克服这个错误吗?

您在文件夹 templates 中创建了一个文件 listenport.j2

{% for item in jsondata[1].domain  if item.server is defined and (item.server | selectattr('listen_port', 'defined')) != [] %}
{{ item.server.0.name }}_httpport:  {{ (item.server | selectattr('listen_port', 'defined')| list).0.listen_port }}
{% endfor %}

剧本:

  - name: ReadJsonfile
    hosts: localhost
    tasks:
      - name: Display the JSON file content
        shell: "cat ./file2.json"
        register: result

      - name: save the Json data to a Variable as a Fact
        set_fact:
          jsondata: "{{ result.stdout | from_json }}"
        
      - name: template
        template:
          src: listenport.j2
          dest: "{{ playbook_dir }}/wlsdatadump.yml"

文件 wlsdatadump.yml 中的结果:

AdminServer_httpport:  12400
myserv1_httpport:  22421

如果您在很多主机上工作(不仅在本地主机上)并且只想在本地主机上创建文件,请在任务中使用 delegate_to: localhost