MAC本如何優雅的創建定時任務


在MACOS上設置定時任務大體有兩種方案。一種是使用crontab,一種是使用Schedule,今天結合我的使用簡單介紹一下。

先說一下背景,為什么MAC可以用crontab。如果使用過Linux的同學,設置定時任務經常會使用crontab、nohup。蘋果根據FreeBSD開發了Mac OS,后續的每一個新版本的Mac OS系統都很大程度上保留了FreeBSD的新特性。當然也包括Shell,也包括crontab。

適用的場景,舉個例子,公司每天下午4點鍾准時訂餐,錯過可能就要餓肚子了(吐舌頭),為了在繁忙的工作中,還能夠記起這個事情,決定設置個定時任務提醒自己。

我第一選擇了寫個簡單的applescript。

on  callmeican ( )
     set  meican_url  to  "https://meican.com"  as  string
     tell  application  "Google Chrome"
         open location  meican_url
         activate
     end tell
end  callmeican
 
say  "不要這么拼了,預訂美餐時間到了"
 
display dialog  "不要這么拼了,預訂美餐時間到了(截至時間16:30)!"  buttons  { "好的" ,  "我不定了" }  default button  1
 
if  the  button  returned  of  the  result  is  "好的"  then
     -- action for 1st button goes here
     callmeican ( )
end if

腳本的作用大概是MAC會通過彈窗和語音提醒我該訂餐了,如果選擇定,就自動用瀏覽器打開訂餐的頁面。這個腳本每天在四點執行。

1、使用crontab設置定時任務

crontab -e 或者sudo crontab -e。

00 16 * * * osascript /Users/hanlingzhi/project/applescript/meican.scpt

輸入完成后,保存退出。系統自動建立新cron,提示如下:crontab: installing new crontab。設置非常簡單。

2、使用蘋果的Schedule jobs using launchd設置定時任務。需要寫一個plist文件,描述任務的動作、間隔的時間、日志輸出等參數。

我創建一個plist文件com.hanlingzhi.cron.meican.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.hanlingzhi.cron.meican</ string >
     <!-- 命令, 第一個為命令,其它為參數-->
     < key >ProgramArguments</ key >
     < array >
         < string >osascript</ string >
       < string >/Users/hanlingzhi/project/applescript/meican.scpt</ string >
     </ array >
     <!-- 運行時間 -->
     < key >StartCalendarInterval</ key >
     < dict >
       < key >Minute</ key >
       < integer >0</ integer >
       < key >Hour</ key >
       < integer >16</ integer >
     </ dict >
     <!-- 標准輸入文件 -->
     < key >StandardInPath</ key >
     < string >/Users/hanlingzhi/project/applescript/log/run-in-meican.log</ string >
     <!-- 標准輸出文件 -->
     < key >StandardOutPath</ key >
     < string >/Users/hanlingzhi/project/applescript/log/run-out-meican.log</ string >
     <!-- 標准錯誤輸出文件 -->
     < key >StandardErrorPath</ key >
     < string >/Users/hanlingzhi/project/applescript/log/run-err-meican.log</ string >
   </ dict >
</ plist >

然后將plist文件放在/Users/hanlingzhi/Library/LaunchAgents,你的用戶目錄下,然后執行launchctl load plist就可以啟動了。

plist腳本存放路徑為/Library/LaunchDaemons或用戶目錄/Library/LaunchAgents,其區別是后一個路徑的腳本當用戶登陸系統后才會被執行,前一個只要系統啟動了,哪怕用戶不登陸系統也會被執行。

  • 系統定義了幾個位置來存放任務列表

  • ~/Library/LaunchAgents 由用戶自己定義的任務項
  • /Library/LaunchAgents 由管理員為用戶定義的任務項
  • /Library/LaunchDaemons 由管理員定義的守護進程任務項
  • /System/Library/LaunchAgents 由Mac OS X為用戶定義的任務項
  • /System/Library/LaunchDaemons 由Mac OS X定義的守護進程任務項

可以通過兩種方式來設置腳本的執行時間。一個是使用StartInterval,它指定腳本每間隔多長時間(單位:秒)執行一次;另外一個使用StartCalendarInterval,它可以指定腳本在多少分鍾、小時、天、星期幾、月時間上執行,類似如crontab的中的設置。

< key >StartInterval</ key >
< integer >3600</ integer >
或者
< key >StartCalendarInterval</ key >
< dict >
   < key >Minute</ key >
   < integer >30</ integer >
   < key >Hour</ key >
   < integer >9</ integer >
</ dict >

launchctl的命令使用大家看一下幫助文檔。

由於操作還是比較復雜,為了幫助快速執行,寫了個shell快速拷貝新的plist並完成服務重啟

__path= '/Users/hanlingzhi/project/applescript'
__plist_path=${__path} /plist
__launchagents_path= '/Users/hanlingzhi/Library/LaunchAgents'
# 拷貝plist到用戶自己定義的任務項目錄
cp  -rf ${__plist_path}/* ${__launchagents_path}
# 根據plist中的文件遍歷load
for  plist_file  in  ` ls  ${__plist_path}`
do
     echo  "重啟${plist_file}定時任務"
     launchctl unload ${__launchagents_path}/${plist_file}
     sleep  0.5
     launchctl load ${__launchagents_path}/${plist_file}
     task_name=` echo  ${plist_file} |  sed  's/.plist//g' `
     launchctl list |  grep  ${task_name}
done

 


總結一下

雖然plist的設置會復雜很多。但是當前在mac os還是傾向於推薦使用Plist的方法,crontab已不推薦使用。

兩者的區別:

1、plist可以設置到秒,而crontab只能到分鍾。

2、plist可以同時應用於Mac OS/Iphone。

3、plist對於MAC上系統交互的操作更支持(我就出現過用crontab設置,運行時出現execution error: 不允許用戶交互。 (-1713)的錯誤)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM