使用launchctl list 查看项目状态,状态码出现 78 的问题

状态码 78launchctl list 的输出中表示该服务启动后进程退出,退出码为 78。这是被管理的程序自身返回的错误码(并非 launchd 的故障),通常是程序未能成功运行或遇到了配置问题。

1. 状态码 78 的含义

launchctl list 显示的结果中,状态列(STATUS)对应服务进程最后一次退出的状态码。78 是常见的自定义退出码,常见于以下情况:

  • Python 脚本语法错误:当 Python 解释器遇到语法错误时,会返回非零退出码(通常为 1 或 2),但某些自定义脚本可能会返回 78。
  • 端口占用:Flask 开发服务器默认使用 5000 端口,如果端口已被占用,程序退出可能返回特定码。
  • 依赖缺失:Python 脚本中 import 模块失败,导致异常退出。
  • 路径或权限问题:无法找到工作目录、文件无权限、Python 解释器路径错误等。
  • 环境变量未设置:脚本需要的环境变量(如 FLASK_APPPATH)缺失。

2. 排查步骤

2.1 查看服务日志

在 plist 中配置了 StandardOutPathStandardErrorPath,检查这两个文件的内容:

cat ~/myflaskapp/logs/flask.err
cat ~/myflaskapp/logs/flask.log

错误日志中通常会包含 Python 的异常信息,例如:

ModuleNotFoundError: No module named 'flask'

OSError: [Errno 48] Address already in use

2.2 手动运行脚本

从终端手动执行 plist 中 ProgramArguments 指定的命令,看是否能正常运行,以及退出码是什么。

cd /Users/yourname/myflaskapp
/Users/yourname/myflaskapp/venv/bin/python3 app.py

如果手动执行时也退出并返回 78,则说明程序本身存在问题。

2.3 检查端口占用

Flask 默认端口 5000,检查是否已被其他进程占用:

lsof -i :5000

如果端口被占用,可以修改 app.run(port=5001) 或 kill 占用进程。

2.4 检查 Python 环境

确认 plist 中使用的 Python 解释器路径是否正确,虚拟环境是否存在且已激活。

ls -l /Users/yourname/myflaskapp/venv/bin/python3

同时,确认脚本中使用的库已安装在虚拟环境中。可尝试在虚拟环境中运行 pip list 检查依赖。

2.5 检查工作目录和文件权限

确保 WorkingDirectory 指定的目录存在且可读,脚本文件有执行权限(通常不需要执行权限,但需可读)。确保日志目录存在且可写。

2.6 检查 plist 语法

运行以下命令检查 plist 文件是否有语法错误:

plutil ~/Library/LaunchAgents/com.yourname.flaskapp.plist

如果输出 OK,则语法正确。

2.7 查看系统日志

如果以上未发现问题,查看 launchd 的系统日志:

log show --predicate 'subsystem == "com.apple.launchd"' --last 1h | grep com.yourname.flaskapp

这可以帮助确认 launchd 在加载或启动服务时是否有错误(例如找不到可执行文件)。

我的笔记