Ubuntu16.04下Python2.7调用Fabric执行任务报-u未找到错误
故障原因与修复方案
报错1:/bin/sh: 2: -u: not found
根因:你构造的fab命令中,-H参数后跟的IP列表混入了换行符,导致shell将换行后的-u识别为独立命令,触发找不到命令的报错。你的IP是动态收集的,大概率是收集逻辑输出的IP末尾带了换行,拼接进命令后打断了原有参数结构。
报错2:close failed in file object destructor: sys.excepthook is missing lost sys.stderr
根因:这是Python2.7的已知问题,你用subprocess.Popen捕获了stdout但没有主动读取缓冲区内容,也没有等待子进程执行完成,主进程提前退出时管道文件对象销毁异常就会抛出该报错。
修复步骤
- 清洗IP列表:拼接命令前先移除IP列表中的所有空白符、换行符,避免破坏命令结构
- 规范subprocess调用逻辑:要么不捕获不需要的输出,要么主动读取缓冲区+等待子进程执行完成
- 可选:优化Fabric脚本权限逻辑:上传bash脚本后先加执行权限,避免偶发权限不足问题
修复后的Python脚本示例
import subprocess ip_list = "192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5" # 清洗IP列表,移除换行、空格等无效字符 ip_list = ip_list.strip().replace('\n', '').replace(' ', '') cmd2 = "fab -f /home/user/fabfile.py -H {} -u user -p password auto_install".format(ip_list) # 不需要捕获输出的写法,直接继承父进程终端输出,便于调试 proc2 = subprocess.Popen(cmd2, shell=True) # 等待fab命令执行完成再退出主进程 proc2.wait() # 如果需要捕获输出排查问题,用以下写法: # proc2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stdout, stderr = proc2.communicate() # print("执行输出:", stdout) # print("错误输出:", stderr)
优化后的Fabric脚本示例
put("/home/user/bash_script","/home/user/bash_script",False) # 给脚本加执行权限 sudo('chmod +x /home/user/bash_script') sudo('bash /home/user/bash_script')
内容的提问来源于stack exchange,提问作者Aurèle Petit
相关产品推荐
相关产品推荐

