You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible执行Python脚本报错:被当作JSON/YAML解析而非执行

问题:Ansible执行Python脚本时误将其当作JSON/YAML解析报错

问题现象

本地运行Python端口测试脚本可得到预期输出,但通过Ansible远程执行时,Ansible错误地将Python文件识别为JSON/YAML格式的Playbook,抛出解析失败的错误。

错误信息

ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
did not find expected

The error appears to be in '/etc/ansible/playbooks/splunk/splunk.py': line 8, column 1, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

#Function that gets stored as the splunkDNS variable then used in the first try/except
def get_ip(hostname):
^ here

相关文件内容

1. splunk.yml Playbook

---
- hosts: local
  become: False


  - name: Copy local python script copy to remote
    ansible.builtin.copy:
      src: /etc/ansible/playbooks/splunk/splunk.py
      dest: /root/splunk.py

  - name: Execute Python Script using the raw module
    ansible.builtin.raw: python3 /root/splunk.py
    register: result

  - debug:
      msg: "{{ result }}"

2. splunk.py 端口测试脚本

#!/bin/python

from contextlib import closing
import os, subprocess, sys, socket
import ipaddress, random, struct

#Function that gets stored as the splunkDNS variable then used in the first try/except
def get_ip(hostname):

        return list(
                i
                        [4]
                        [0]
                for i in
                socket.getaddrinfo(
                        hostname,
                   80
                )
                if i[0] is socket.AddressFamily.AF_INET
                and i[1] is socket.SocketKind.SOCK_RAW
        )

def get_ip_from_subnet(ip_subnet):
        ips=ipaddress.ip_network(ip_subnet)
        ip_list=[str(ip) for ip in ips]
        return ip_list

splunkDNS=get_ip('splunk.com') #Uses the function above to get the IP of the splunk-local domain
hostname=os.getenv('HOSTNAME')
ip_subnet="1.5.1.128/25"
ip_list= get_ip_from_subnet(ip_subnet)
randIp = ip_list[random.randint(0,len(ip_list))]

print("Hostname: " + str(hostname))

#Check DNS resolution
try:
        if '1.5.1.95' in splunkDNS: #If that .95 IP is anywhere in the output of the get_ip function this returns True.
                print("DNS Resolution to Splunk is working!")
        else:
                print("DNS resolution to splunk.com has failed!\nPlease verify that /etc/resolv.conf contains the following entries: ")
except Exception as e:
        print("Something went wrong! - DNS Step")
        print(e)
#Check if the current machine can send traffic on 1.5.1.95:8089
try:
        def check_socket(host, port):
                with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
                        if sock.connect_ex((host, port)) == 0:
                                print("Can send traffic on 1.5.1.95:8089")
                        else:
                                print("Cannot connect to 1.5.1.95:8089!\n\n")
        splunkPort=check_socket('1.5.1.95', 8089)
except Exception as e:
        print("Something went wrong! - 8089 Traffic Step")
        print(e)
try:
        print("Testing the IP: "+randIp)

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = sock.connect_ex((randIp,9997))
        if result == 0:
                print("Port 9997 is open on " + randIp)
        else:
                print("Port 9997 is not open on " + randIp)
        sock.close()

except Exception as e:
        print("Something went wrong! - Random IP Step")
        print(e)

3. hosts 配置文件

[local]
localhost

解决方案

核心问题定位

报错的直接原因是执行Ansible时指定了错误的文件作为Playbook——你大概率误将splunk.py当作Playbook运行(比如执行ansible-playbook splunk.py),而Ansible会强制解析传入的文件为YAML/JSON格式的Playbook,因此触发语法错误。

正确执行步骤

  1. 确保执行的是Playbook文件splunk.yml,而非Python脚本:
    ansible-playbook /etc/ansible/playbooks/splunk/splunk.yml -i hosts
    
  2. 额外优化建议:
    • 使用ansible.builtin.script模块替代"copy+raw"的组合,一步完成脚本传输与执行,更简洁高效:
      修改splunk.yml中的任务:
      - name: Execute Python Script directly
        ansible.builtin.script: /etc/ansible/playbooks/splunk/splunk.py
        register: result
      
    • 给Python脚本添加可执行权限:
      chmod +x /etc/ansible/playbooks/splunk/splunk.py
      
    • 修复脚本中randIp的越界问题:random.randint(0, len(ip_list))会取到超出列表索引范围的值,修改为:
      randIp = ip_list[random.randint(0, len(ip_list)-1)]
      

内容的提问来源于stack exchange,提问作者Gabe_H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:03:27