You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LaunchDaemon无法找到bash命令问题排查求助

问题:LaunchDaemon触发bash脚本时无法正确执行blueutil命令

场景说明

我在MacBook上编写了一个bash脚本,用来根据WF-1000XM3蓝牙耳机的连接状态自动启用/禁用睡眠,实现合盖听歌时不受干扰。脚本存放于/Users/klumpy/Library/Scripts目录,由LaunchDaemon每5秒触发一次,依赖brew安装的blueutil命令。

原脚本内容

#!/usr/bin/env
export PATH=$(cat /Users/klumpy/Library/Scripts/PATH)
export BLUEUTIL_ALLOW_ROOT=1
# Check if "WF-1000XM3 is connected, if yes disable sleep, if not, don't go to sleep.
echo $(blueutil --connected)
echo $(blueutil --connected | grep "WF-1000XM3")
if [[ $(blueutil --connected | grep "WF-1000XM3" -c) -ne 0 ]]; then
  sudo pmset disablesleep 1
  echo "Sleep Disabled"
else
  sudo pmset disablesleep 0
  echo "Sleep Enabled"
fi

原LaunchDaemon 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.example.bluetoothsleep</string>
    <key>ProgramArguments</key>
    <array>
      <string>sudo</string>
      <string>bash</string>
      <string>/Users/klumpy/Library/Scripts/disablesleep</string>
    </array>
    <key>StandardErrorPath</key>
      <string>/Users/klumpy/Documents/Programming/bin/stderr.txt</string>
    <key>StandardOutPath</key>
      <string>/Users/klumpy/Documents/Programming/bin/stdout.txt</string>
    <key>StartInterval</key>
      <integer>5</integer>
  </dict>
</plist>

问题现象

  • 脚本在终端运行完全正常,但LaunchDaemon触发时找不到blueutil命令;
  • 最初打印$PATH仅得到/usr/bin:/bin:/usr/sbin:/sbin,将终端$PATH内容存入脚本同目录的PATH文件并导出后,脚本输出只剩“Sleep Enabled”,前两条echo无内容;
  • 无论耳机是否连接,脚本始终走else分支,完全无法识别耳机状态。

错误原因及修复方案

1. 修复脚本shebang错误

原脚本第一行#!/usr/bin/env不完整,未指定具体shell,LaunchDaemon可能默认用sh执行,导致语法和环境差异。修改为:

#!/usr/bin/env bash

2. 直接指定blueutil绝对路径,避免PATH问题

brew安装的blueutil路径分两种:

  • Apple Silicon Mac:/opt/homebrew/bin/blueutil
  • Intel Mac:/usr/local/bin/blueutil

在脚本里直接用绝对路径调用,彻底规避PATH配置的坑:

# 根据自己的Mac架构选择路径
BLUEUTIL_PATH="/opt/homebrew/bin/blueutil"
# BLUEUTIL_PATH="/usr/local/bin/blueutil"

3. 移除LaunchDaemon中的冗余sudo

LaunchDaemon本身以root身份运行,无需在ProgramArguments里加sudo——sudo会重置环境变量,导致之前配置的PATH失效。修改plist的ProgramArguments:

<key>ProgramArguments</key>
<array>
  <string>/bin/bash</string>
  <string>/Users/klumpy/Library/Scripts/disablesleep</string>
</array>

同时脚本里的sudo pmset也可以去掉sudo,root身份运行不需要额外授权。

4. 优化脚本逻辑,减少重复调用

原脚本重复执行blueutil --connected三次,既低效又可能导致状态不一致,改为先把结果存到变量里再复用:

connected_devices=$($BLUEUTIL_PATH --connected)
echo "$connected_devices"
echo "$connected_devices" | grep "WF-1000XM3"

if echo "$connected_devices" | grep -q "WF-1000XM3"; then

修复后的完整脚本

#!/usr/bin/env bash
# 根据Mac架构选择对应路径
BLUEUTIL_PATH="/opt/homebrew/bin/blueutil"
# BLUEUTIL_PATH="/usr/local/bin/blueutil"
export BLUEUTIL_ALLOW_ROOT=1

connected_devices=$($BLUEUTIL_PATH --connected)
echo "$connected_devices"
echo "$connected_devices" | grep "WF-1000XM3"

if echo "$connected_devices" | grep -q "WF-1000XM3"; then
  pmset disablesleep 1
  echo "Sleep Disabled"
else
  pmset disablesleep 0
  echo "Sleep Enabled"
fi

修复后的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.example.bluetoothsleep</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/bash</string>
      <string>/Users/klumpy/Library/Scripts/disablesleep</string>
    </array>
    <key>StandardErrorPath</key>
      <string>/Users/klumpy/Documents/Programming/bin/stderr.txt</string>
    <key>StandardOutPath</key>
      <string>/Users/klumpy/Documents/Programming/bin/stdout.txt</string>
    <key>StartInterval</key>
      <integer>5</integer>
  </dict>
</plist>

内容的提问来源于stack exchange,提问作者Klumpy7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:26:05