跳到正文
FunCoding

搜索

搜索文档、Skill 和 MCP

macOS 常驻与临时后台

配置 launchd 的绝对路径、私有凭据和失败重启,并比较 tmux 与 nohup。

macOS launchd 不展开 ~ 或 shell 变量,也不读取交互 profile。先用 which qwen gh git npm node 确认可执行路径,把所需可信目录写进服务 PATH。

LaunchAgent 模板

保存到 ~/Library/LaunchAgents/com.qwenlm.qwen-serve.plist,替换用户名、qwen 路径、工具目录和 token。不要提交带真实 token 的 plist。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.qwenlm.qwen-serve</string>
  <key>ProgramArguments</key>
  <array>
    <string>/PATH/TO/qwen</string><string>serve</string>
    <string>--hostname</string><string>127.0.0.1</string>
    <string>--port</string><string>4170</string>
    <string>--require-auth</string>
    <string>--workspace</string><string>/Users/YOUR-USERNAME/project-a</string>
  </array>
  <key>WorkingDirectory</key><string>/Users/YOUR-USERNAME/project-a</string>
  <key>EnvironmentVariables</key>
  <dict>
    <key>PATH</key><string>/PATH/TO/USER/BIN:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
    <key>QWEN_SERVER_TOKEN</key><string>PASTE-YOUR-TOKEN-HERE</string>
  </dict>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
  <key>ThrottleInterval</key><integer>10</integer>
  <key>StandardOutPath</key><string>/Users/YOUR-USERNAME/Library/Logs/qwen-serve/out.log</string>
  <key>StandardErrorPath</key><string>/Users/YOUR-USERNAME/Library/Logs/qwen-serve/err.log</string>
</dict>
</plist>

SuccessfulExit=false 表示失败重启,避免无条件 KeepAlive 在干净退出后也立即重启;ThrottleInterval=10 限制持续失败时的启动频率。示例使用 require-auth,因此 health 也需要令牌。

加载、停止和轮换

mkdir -p ~/Library/Logs/qwen-serve
chmod 600 ~/Library/LaunchAgents/com.qwenlm.qwen-serve.plist
launchctl load ~/Library/LaunchAgents/com.qwenlm.qwen-serve.plist

停止时执行:

launchctl unload ~/Library/LaunchAgents/com.qwenlm.qwen-serve.plist

修改 plist 或轮换 token 后,unload 再 load 才生效。官方模板提醒 load 会截断指定输出日志,排障前先保存需要的旧日志。Daemon 自己的轮转日志是另一套文件,不与 launchd 重定向混淆。

生成新 plist 后重新设置 0600。重新启动后在新 agent 会话检查工具 PATH,避免误以为终端中可用就代表 launchd 下可用。

临时后台运行

tmux 适合保留可随时查看的终端输出;在启动它的 shell 中提供 QWEN_SERVER_TOKEN 后:

tmux new -d -s qwen-serve "qwen serve --hostname 127.0.0.1 --workspace /absolute/path/project-a"
tmux attach -t qwen-serve

Ctrl-b d 脱离,停止使用 tmux kill-session -t qwen-serve。tmux 可跨终端关闭,但不跨主机重启,也不自动恢复崩溃的 daemon。

一次性试验可使用:

nohup qwen serve --hostname 127.0.0.1 \
  --workspace /absolute/path/project-a \
  > qwen-serve.log 2>&1 &
echo $!

记录 PID 后才能有目标地停止;nohup 没有失败重启,日志也不会自动限长。需要持续常驻时使用 launchd 或systemd。

独立后台方式仍需同样的认证、工作区信任和会话恢复处理。把进程留在后台不意味着任务可以跨重启自动继续。