2020年4月14日火曜日

Mac で Bluetooth デバイスが接続されたときに任意のスクリプトを実行する方法

概要

Mac の LaunchAgents という仕組みを使うと Bluetooth の接続/切断のイベントをハンドリングすることができます
launchctl の仕組みを使っているので XML 形式で定義ファイルを登録しておくことでイベント発生時に任意のスクリプトやコマンドを実行することができます

環境

  • macOS 10.15.4

何かしらの Bluetooth デバイスが接続されたときにファイルを作成する

まずは何でもいいので Bluetooth デバイスが接続されたらファイルを作成するような LaunchAgents を登録してみます

  • vim ~/Library/LaunchAgents/local.mac.bluetooth_handler.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>Keyboard Connect/Disconnect Handler</string>

    <key>ProgramArguments</key>
    <array>
      <string>touch</string>
      <string>/Users/hawksnowlog/Downloads/test</string>
    </array>

    <key>WatchPaths</key>
    <array>
      <string>/Library/Preferences/com.apple.Bluetooth.plist</string>
    </array>
  </dict>
</plist>
  • launchctl load ~/Library/LaunchAgents/local.mac.bluetooth_handler.plist

ポイントは WatchPaths で Bluetooth 機器を管理している /Library/Preferences/com.apple.Bluetooth.plist を監視する点です
あとは ProgramArguments で実行するコマンドを指定します

これで Bluetooth デバイスを接続するとファイルが作成されているのが確認できます

MagicKeyboard2 が Bluetooth で接続されたらファイルを作成する

次に特定の Bluetooth 機器が接続されたときにだけファイルを作成するようにします
さすがにコマンド一つで解決できないのでシェルスクリプトを書くことでデバイスの特定と実行する処理を実装します

  • vim ~/Library/LaunchAgents/local.mac.bluetooth_handler2.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>MagicKeyboard Connect/Disconnect Handler</string>

    <key>ProgramArguments</key>
    <array>
      <string>/Users/hawksnowlog/Library/Scripts/keyboard.zsh</string>
    </array>

    <key>WatchPaths</key>
    <array>
      <string>/Library/Preferences/com.apple.Bluetooth.plist</string>
    </array>
  </dict>
</plist>

Bluetooth 機器が接続されたときに keyboard.zsh を実行するようにします
このシェル自体はどんな Bluetooth 機器が接続/切断されても呼ばれてしまうので機器の特定をスクリプトないで行います

  • vim ~/Library/Scripts/keyboard.zsh
#!/bin/zsh
sleep 3
val=`system_profiler SPBluetoothDataType | grep -A 3 "Services: Magic Keyboard$" | grep "Connected: Yes" | wc -l`
if [ $val -eq "1" ]
then
  touch /Users/hawksnowlog/Downloads/ok
fi

system_profiler SPBluetoothDataType で Bluetooth 機器の状態を確認できます
あとは MagicKeyboard の部分を見て Connected が Yes だった場合に任意のコマンドを実行するだけです
keyboard.zsh は実行権限が必要なので付与しておきます

  • chmod 755 ~/Library/Scripts/keyboard.zsh
  • launchctl load ~/Library/LaunchAgents/local.mac.bluetooth_handler.plist

これで MagicKeyboard が接続されたときだけファイルが作成されるのが確認できると思います
ただ上記スクリプトだと MagicKeyboard が接続された状態で別の Bluetooth デバイスがされてもファイルが作成されてしまうので少し改良が必要です

最後に

Mac に任意の Bluetooth デバイスが接続/切断されたときに指定したスクリプトやコマンドを実行する方法を紹介しました
launchctl の LaunchAgents という仕組みを使っているので launchctl に慣れている人は簡単に書けると思います

おまけ: systemprofile に指定可能なタイプの一覧を取得する方法

  • system_profiler -listDataTypes

参考サイト

0 件のコメント:

コメントを投稿