open smb://...でSMB共有をマウントすると、認証ダイアログの表示を伴う場合もある。パスワードがキーチェーンに保存されていて入力済みでも、「接続」ボタンは手動で押す必要がある。接続が切れるたびに再マウントする長時間のジョブでは、毎回ボタンを押しに行くのは現実的でない。
osascriptでAppleScriptを実行すると、ダイアログの「接続」ボタンを自動でクリックできる。ダイアログを表示しているプロセスはNetAuthAgentである。
$ osascript -e 'tell application "System Events" to exists process "NetAuthAgent"'
false
ダイアログが表示されているときはtrueになる。実行例はmacOS 27.0.1のもの。
参考: 【mount_smbfs】SMB共有をダイアログなしでゲストマウントする (-N)
アクセシビリティの権限を許可する
他のアプリのウィンドウを操作するAppleScriptは、System Eventsを経由して実行する。実行するターミナルアプリに、アクセシビリティの権限が必要である。
- 「システム設定」の「プライバシーとセキュリティ」から、「アクセシビリティ」を開く
- 使用しているターミナルアプリを追加して、オンにする
権限があると、ウィンドウの一覧を取得できる。Finderのウィンドウ名を取得して確認する例である。
$ osascript -e 'tell application "System Events" to tell process "Finder" to get name of every window'
Downloads
「接続」ボタンをクリックするスクリプト
3秒ごとにNetAuthAgentのウィンドウを確認して、「接続」ボタンがあればクリックするスクリプトである。パスワード欄には触らない。
#!/bin/zsh
# usage: click-connect.sh <log-file>
log=$1
while true; do
out=$(osascript <<'AS' 2>&1
tell application "System Events"
if not (exists process "NetAuthAgent") then return "none"
tell process "NetAuthAgent"
if (count of windows) = 0 then return "nowindow"
set w to window 1
set names to {}
repeat with b in (buttons of w)
set end of names to name of b
end repeat
repeat with n in {"接続", "Connect"}
if exists button n of w then
click button n of w
return "clicked " & n
end if
end repeat
return "nobutton: " & (names as string)
end tell
end tell
AS
)
case $out in
none|nowindow) ;;
*) echo "$(date '+%T') $out" >> "$log" ;;
esac
sleep 3
done
スクリプトの流れ
AppleScriptは、次の順に判断して、結果を文字列で返す。
| 返り値 | 状況 |
|---|---|
none | NetAuthAgentのプロセスがない。ダイアログは表示されていない |
nowindow | プロセスはあるが、ウィンドウがない |
clicked 接続 | 「接続」ボタンを見つけてクリックした |
nobutton: ... | 「接続」もConnectもなかった。ウィンドウにあるボタンの名前を返す |
シェルスクリプトは、noneとnowindowを無視して、それ以外をログに追記する。ダイアログが表示されていない間は、ログが空のままである。
ボタンの名前は、ダイアログの表示言語で変わる。日本語表示では「接続」、英語表示ではConnectを想定して、両方を探している。想定外の名前のときは、nobutton: ...の後ろにボタンの名前が記録される。その名前を{"接続", "Connect"}に追加する。
AppleScriptをヒアドキュメントで渡す
osascriptにはヒアドキュメント(<<'AS')で複数行のAppleScriptを渡せる。'AS'のようにクォートすると、シェルが$などを展開しない。2>&1でエラーも標準出力に含めて、$(...)で結果を変数に代入している。
バックグラウンドで実行する
マウントを実行する側のスクリプトとは別に、バックグラウンドで常駐させる。
$ chmod +x click-connect.sh
$ nohup ./click-connect.sh ~/click-connect.log >/dev/null 2>&1 &
「接続」ボタンをクリックすると、ログに時刻つきで記録される。
$ cat ~/click-connect.log
18:06:13 clicked 接続
18:09:29 clicked 接続
ジョブが終わったら、常駐を止める。
$ pkill -f click-connect.sh
常駐させている間は、NetAuthAgentのあらゆるダイアログで「接続」ボタンをクリックする。意図しないサーバーへの接続を求めるダイアログがあっても、押してしまう。長時間のジョブに必要な間だけ実行する。
