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

获取subprocess执行返回值 解决ping连通性测试自定义函数运行异常问题

现存问题梳理

  • 直接在subprocess.Popen的args参数中写管道符|无法生效:管道是shell提供的功能,默认执行模式下Popen会把|当成普通参数传给ping命令,无法实现你想要的结果过滤效果。
  • 命令参数拆分错误:grep -E -o、"[0-9]+ received"、cut -f1 -d这些写法不符合args的拆分规则,每个空格分隔的参数都要单独作为元组的元素,且cut的-d参数没有指定分隔符(此处应该是空格)。
  • 逻辑判断错误:if (popen == 1)完全不符合逻辑,popen是进程对象,不是执行结果,你需要读取进程的标准输出内容做判断。
  • 冗余的sudo权限:ping命令普通用户即可执行,不需要加sudo提升权限。

修正方案

方案1:开启shell支持,适配小工具场景

如果是个人使用的小工具,可以直接开启shell=True支持管道语法,写法更简洁:

import subprocess

def testConnection(ip):
    TIMEOUT = 10
    # 整段命令作为字符串传入
    cmd = f"ping -c 1 -q {ip} | grep -E -o '[0-9]+ received' | cut -f1 -d' '"
    try:
        popen = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        stdout, stderr = popen.communicate(timeout=TIMEOUT)
        recv_count = stdout.strip()
        if recv_count == '1':
            print(ip + " is up")
            return True
        else:
            print(ip + " is down")
            return False
    except subprocess.TimeoutExpired as e:
        print(e)
        popen.kill()
        return False
    finally:
        if popen.returncode != 0 and recv_count != '0':
            # 需提前自定义ServiceException
            raise ServiceException()

方案2:无外部依赖,适配生产场景

如果是生产环境使用,不建议开启shell=True(存在命令注入风险),可以直接用Python正则解析ping的输出,不需要调用grep、cut:

import subprocess
import re

def testConnection(ip):
    TIMEOUT = 10
    args = ('ping', '-c', '1', '-q', ip)
    recv_pattern = re.compile(r'(\d+) received')
    try:
        popen = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        stdout, stderr = popen.communicate(timeout=TIMEOUT)
        match = recv_pattern.search(stdout)
        if match and match.group(1) == '1':
            print(ip + " is up")
            return True
        else:
            print(ip + " is down")
            return False
    except subprocess.TimeoutExpired as e:
        print(e)
        popen.kill()
        return False
    finally:
        if popen.returncode != 0 and not (match and match.group(1) == '0'):
            raise ServiceException()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 15:12:01