Ubuntu虚拟机GNS3环境下SDN控制器启动及路由流配置脚本问题咨询
解决SDN脚本的多终端运行、延迟控制与curl语法问题
核心问题分析
- 多个服务无法在同一终端同时运行:
os.system是阻塞调用,会等待当前命令执行完毕才继续,且无法自动打开新终端 - 缺少启动延迟:服务启动需要初始化时间,直接执行后续命令会导致失败
- curl语法错误:参数格式错误(
- X多空格)、JSON字符串转义逻辑混乱
分步解决方案
1. 多终端运行实现(Ubuntu环境)
Ubuntu下使用gnome-terminal打开新终端执行命令,配合subprocess.Popen实现非阻塞调用,避免脚本停滞。同时用os.chdir切换工作目录(替代无效的os.system("cd ..."),因为每个os.system都是独立shell进程,目录切换不生效)。
2. 添加启动延迟
导入time模块,在启动服务后调用time.sleep(n)等待服务初始化,n值根据服务实际启动速度调整(比如RYU服务等5秒,ONOS等10秒)。
3. 修复curl命令语法
- 修正
- X为-X(去掉参数与选项间的空格) - JSON数据用单引号包裹外层,内部用双引号,避免转义错误;也可采用双引号外层+转义内部双引号的写法
- 确保curl命令格式合规:
curl -X POST -d '{"address": "10.1.1.2/24"}' http://localhost:8080/router/000056e95a9e4843
完整优化脚本
#!/usr/bin/python3 import os import subprocess import time # 切换到RYU应用目录(全局生效) os.chdir("/home/sdn/Downloads/ryu/ryu/app") print("当前工作目录: ") print(os.getcwd()) print('\n') # 打开新终端启动RYU rest_router.py subprocess.Popen(["gnome-terminal", "--command", "./rest_router.py"]) time.sleep(5) # 等待RYU服务启动 # 打开新终端启动RYU gui_topology.py subprocess.Popen(["gnome-terminal", "--command", "./gui_topology.py"]) time.sleep(3) # 打开新终端启动ONOS控制器 subprocess.Popen(["gnome-terminal", "--command", "sudo /opt/onos/bin/onos-service start"]) time.sleep(10) # ONOS启动较慢,延长等待时间 # 执行curl命令添加流表 curl_cmds = [ 'curl -X POST -d \'{"address": "10.1.1.2/24"}\' http://localhost:8080/router/000056e95a9e4843', 'curl -X POST -d \'{"address": "10.2.2.2/24"}\' http://localhost:8080/router/000056e95a9e4843', 'curl -X POST -d \'{"address": "10.3.3.2/24"}\' http://localhost:8080/router/000056e95a9e4843' ] for cmd in curl_cmds: os.system(cmd) time.sleep(1) # 每个curl请求间隔1秒
额外说明
- 如果你的终端不是
gnome-terminal,替换成对应终端命令(比如konsole、xterm),参数格式可能略有不同 - 延迟时间可根据实际启动速度调整,比如ONOS可能需要15-20秒的等待时间
- 用
subprocess.Popen替代os.system更灵活,方便后续捕获输出或管理进程
内容的提问来源于stack exchange,提问作者Brodie Anderson
相关产品推荐
相关产品推荐

