最近有個想法,就是想在MAC網絡切換的時候,自動根據網絡切換來判斷是辦公環境還是家庭環境,從而執行對應的動作
做技術的都知道,我們在linux下一般用crontab實現定時任務。
在MAC下,我們一般用launchd實現定時任務,以及其他事件觸發的任務。
簡單介紹下launchd,launchd存在於MAC OX的系統進程中,用戶不能直接對該進程進行操作,只能通過launchctl對其進行管理。
launchctl是一個統一的服務管理框架,可以啓動、停止和管理守護進程、應用程序、進程和腳本等。launchctl是通過配置文件來指定執行週期和任務的。配置文件一般是plist類型的文件。
屬性列表(Property List)文件是一種用來存儲序列化後的對象的文件。屬性列表文件的文件擴展名爲.plist,因此通常被稱爲plist文件。Plist文件通常用於存儲用戶設置,也可以用於存儲捆綁的信息,plist中主要的字段和它的含義如下:
- Label用來在launchd中的一個唯一標識,如同每一個程序都有一個identifies一樣。
- UserName指定運行啓動項的用戶,只有當Launchd 作爲 root 用戶運行時,此項才適用。
- GroupName指定運行啓動項的組,只有當Launchd 作爲 root 用戶運行時,此項才適用。
- KeepAlive這個key值是用來控制可執行文件是持續運行,還是滿足具體條件之後再啓動。默認值爲false,也就是滿足具體條件之後才啓動。當設置值爲ture時,表明無條件的開啓可執行文件,並使之保持在整個系統運行週期內。
- RunAtLoad標識launchd在加載完該項服務之後立即啓動路徑指定的可執行文件。默認值爲false。
- Program這個值用來指定進程的可執行文件路徑。
- ProgramArguments這個值用來指定可執行文件和運行的參數。
全部字段含義如下
Key | Description | Required |
Label | The name of the job | yes |
ProgramArguments | Strings to pass to the program when it is executed | yes |
UserName | The job will be run as the given user, who may not necessarily be the one who submitted it to launchd. | no |
inetdCompatibility | Indicates that the daemon expects to be run as if it were launched by?inetd | no |
Program | The path to your executable. This key can save the ProgramArguments key for flags and arguments. | no |
onDemand | A?boolean?flag that defines if a job runs continuously or not | no |
RootDirectory | The job will be?chrooted?into another directory | no |
ServiceIPC | Whether the daemon can speak IPC to launchd | no |
WatchPaths | Allows launchd to start a job based on modifications at a file-system path | no |
QueueDirectories | Similar to WatchPath, a queue will only watch an empty directory for new files | no |
StartInterval | Used to schedule a job that runs on a repeating schedule. Specified as the number of seconds to wait between runs. | no |
StartCalendarInterval | Job scheduling. The?syntax?is similar to?cron. | no |
HardResourceLimits | Controls restriction of the resources consumed by any job | no |
LowPriorityIO | Tells the kernel that this task is of a low priority when doing file system I/O | no |
Sockets | An array can be used to specify what socket the daemon will listen on for launch on demand | no |
plist腳本一般存放在以下目錄:
-
/Library/LaunchDaemons
-->只要系統啓動了,哪怕用戶不登陸系統也會被執行 -
/Library/LaunchAgents
-->當用戶登陸系統後纔會被執行更多的plist存放目錄:
~/Library/LaunchAgents 由用戶自己定義的任務項
/Library/LaunchAgents 由管理員爲用戶定義的任務項
/Library/LaunchDaemons 由管理員定義的守護進程任務項
/System/Library/LaunchAgents 由Mac OS X爲用戶定義的任務項
/System/Library/LaunchDaemons 由Mac OS X定義的守護進程任務項一個簡單的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>onnetworkchange</string>
<key>ProgramArguments</key>
<array>
<string>python</string>
<string>%s</string>
</array>
<key>StandardOutPath</key>
<string>%s</string>
<key>StandardErrorPath</key>
<string>%s</string>
<key>WatchPaths</key>
<array>
<string>/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist</string>
</array>
</dict>
</plist>
launchd加載plist文件命令
launchctl load -w demo.plist
更多命令
#查看 launchctl使用手冊, man在對mac下大部分命令通用,例如 man ifconfig
$ man launchctl
# 加載任務, -w選項會將plist文件中無效的key覆蓋掉,建議加上
$ launchctl load -w zrbdemo.plist
# 刪除任務
$ launchctl unload -w zrbdemo.plist
# 查看任務列表
$ launchctl list
# 開始任務
$ launchctl start zrbdemo.plist
# 結束任務
$ launchctl stop zrbdemo.plist
更多詳情參見apple官方文檔
由於MAC BOOK在切換Wi-Fi網絡時 /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist 文件會發生改變,利用 WatchPaths 屬性即可監聽該文件變化。
參照如上plist示例即可實現監聽MAC網絡改變事件,在觸發事件時執行 ProgramArguments標籤裏配置的腳本文件%s
以上純屬個人見解,有不足之處歡迎評論區噴博主~