如何在PyCharm中通过Shell脚本或Python代码重新运行main.py服务
如何在PyCharm中通过Shell脚本或Python代码重新运行main.py服务
看起来你正在尝试自动重启PyCharm里的Flask服务,踩了不少脚本的坑,还碰到了文件描述符的错误,我来帮你梳理下可行的方案和问题解决办法。
先聊聊你现有脚本的问题
你的第一个脚本依赖PyCharm的Ctrl+R快捷键,但焦点很容易跑到终端或者其他窗口,导致快捷键失效;第二个脚本重启PyCharm的方式太粗暴,而且同样可能因为焦点问题导致快捷键没触发到正确的窗口。另外你遇到的OSError: [Errno 9] Bad file descriptor,一般是旧进程没完全释放端口/文件描述符,新进程启动时就会报错。
方案一:不依赖PyCharm GUI的稳定Shell脚本
最靠谱的方式是直接通过命令行运行你的main.py,完全绕开PyCharm的GUI操作,避免焦点问题。试试这个脚本:
#!/bin/bash # 替换成你的虚拟环境Python路径和main.py路径 VENV_PY="/Backend/.venv/bin/python" MAIN_PY="/Backend/main.py" # 清理占用5001端口的进程 echo "Checking for processes on port 5001..." PID=$(lsof -t -i :5001) if [ -n "$PID" ]; then echo "Killing process $PID..." kill -9 "$PID" sleep 1 # 给进程一点时间彻底退出 else echo "No process found on port 5001." fi # 启动服务 echo "Starting main.py server..." "$VENV_PY" "$MAIN_PY"
这个脚本直接用虚拟环境的Python运行main.py,不需要PyCharm,稳定性拉满。
方案二:针对PyCharm GUI的改进版脚本
如果你必须在PyCharm里操作(比如要用调试功能),那得确保快捷键触发到正确的窗口。试试这个优化后的脚本,先聚焦到PyCharm的Run工具窗口再发送重启命令:
#!/bin/bash # 先清理端口进程 PID=$(lsof -t -i :5001) if [ -n "$PID" ]; then kill -9 "$PID" sleep 1 fi # 激活PyCharm并聚焦到Run窗口再重启 osascript <<EOF tell application "PyCharm Community Edition" activate delay 0.5 tell application "System Events" tell process "PyCharm Community Edition" # 按Alt+4打开Run工具窗口(PyCharm默认快捷键,可根据你的设置调整) keystroke "4" using option down delay 0.3 # 发送Ctrl+R重启服务 keystroke "r" using control down end tell end tell end tell EOF
这样能确保焦点在Run窗口,不会跑到终端或者编辑界面。
方案三:Python代码内实现自动重启
如果不想用Shell脚本,也可以在main.py里加重启逻辑,比如捕获特定错误后自动重启:
import os import sys from flask import Flask app = Flask(__name__) # 你的业务路由 @app.route('/') def index(): return "Server is running!" def restart_server(): print("Restarting server...") # 用execv重启当前进程 os.execv(sys.executable, [sys.executable] + sys.argv) if __name__ == '__main__': try: # 如果不需要自动重载,把debug=True改成False app.run(debug=True, host='0.0.0.0', port=5001) except OSError as e: # 捕获Bad file descriptor错误并重启 if e.errno == 9: restart_server() else: raise
注意:Flask的debug=True本身会自动重载代码改动,但如果是遇到端口占用这类错误,这个逻辑能帮你自动重启。
解决你遇到的OSError问题
那个Bad file descriptor错误,大概率是旧进程没完全释放端口或者文件句柄。你可以:
- 用方案一里的Shell脚本,确保杀进程后等1秒再启动新进程
- 如果用Flask的debug模式,试试关闭它(
debug=False),有时候debug模式的重载机制会导致文件描述符泄漏 - 检查是否有其他进程在占用5001端口,用
lsof -i :5001确认
备注:内容来源于stack exchange,提问作者Denis Popkov
相关产品推荐
相关产品推荐

