Mac OSX 是一個很特殊的系統,在 OS 9 之前有著自己的系統架構及腳本語言,而與 Unix 融合之後 (使用 BSD 核心) 也沒有完全拋棄過去,多種不同的架構在系統中並行,像是數種作業系統的綜合體。
這次來聊聊腳本 (Script) 指令的打包。OSX 支援兩種腳本語言,一種是 Mac OS 原有的 Applescript,另一種是從 Unix 架構繼承來的 Shell script。這兩種腳本語言有很多功能是重疊的,也就是說很多事情兩者都能辦到,使用者選一種寫就好了,但有一些則是某一語言的專屬功能。比如說控制其他軟體的一些行為就是 Applescript 的特長;Shell script 則是擅長系統層面及檔案系統的快捷功能 [1]。不管要執行什麼指令,每次都要打開 Applescript editor (工序指令編寫程式) 或 Terminal (終端機) 再次輸入實在頗煩的,而把這些指令打包成一個應用程式或是可直接執行的腳本檔案可以省去不少時間。
製作可執行的 shell script
這個方法就是把指令存在純文字檔中,然後給它 *.sh 的副檔名,最後加上 "可執行" 的權限即可 (參考資料):
chmod 744 [檔案路徑]有趣的是,*.sh 在 Linux 中可直接執行,像拉進 Terminal 執行或是直接點兩下執行都可以,但在 OSX 裡只支援在 Terminal 內執行,如果要直接執行還得將檔名改成 *.command 才行。
用 Automator 打包
Automator 是 Apple 在 OSX 10.4 時推出的圖形化工具,目的就是把 Applescript 控制其他軟體的部份獨立出來,讓使用者可以不用寫程式就能製作出符合自己需求的工作流程 (Workflow)。Automator 做到 "讓寫程式簡單化" 的偉大目標,但它可不完全是初學者的玩具,因為它不僅支援的軟體功能很多,而且也可以插入 Applescript 或 Shell script 的程式碼去進行更進階的操作。我個人最常用的是 "服務" 功能,這種包裝方式可以把我的指令製作成右鍵選單 (服務選單),進而對選定的檔案或文字進行操作。
用 Applescript Editor 打包
Applescript Editor 是 Applescript 專用的 Terminal 及 IDE,也是最簡單且最直覺的打包方法,只要打好指令並匯出成 "應用程式" 即可,原始碼就存成腳本檔 (*.scpt)。
如何打包一個需要 root 權限的指令?
有些指令要動到系統檔案,或是動到其他使用者的檔案,此時就需要終極管理者 -- root 的權限才能執行該指令。Unix-like 的系統提供 sudo 指令,可以讓用戶暫時擁有 root 的權限。但是,不是每個使用者都可以使用 sudo 指令,一般是記在 /etc/sudoers 的列表裡。Mac OSX 裡的使用者分為一般帳戶及管理者帳戶,而只有後者能使用 sudo,故我在 Unlocker for Mac 一文中提到使用 su 或 su - 指令更換使用者以使用 sudo。
但是 su 及 sudo 的組合沒辦法用在打包的指令裡,故必須找其他的方法。Shell script 不鼓勵使用者把 sudo 指令寫在打包的 script 檔內,而是用 sudo 執行該程式:
sudo 我的script.sh但 Applescript 支援此功能!利用 do shell script .... with administrator privileges 來執行需 root 權限的指令,例子如下 (參考資料):
do shell script "我的指令" user name "管理者帳號" password "管理者密碼" with administrator privileges看起來很美好,可是把帳號密碼寫在檔案裡確實不太安全,故建議調出認証視窗,每次執行時都輸入一次管理者的帳號及密碼。作法很簡單,就是把 user name 及 password 的敘述拿掉,下面是我實際使用的例子:
上圖指令為我在 "Mac OSX 的系統維護與疑難排解 2" 中介紹的 periodic 系統維護指令,第二行則是提醒我維護作業完成的彈出式對話框。
看到這裡,或許有人會說:「打包程式幹嘛不用 Platypus?」我的經驗是,除非你想把好幾個腳本檔打包在一起,或是打包 droplet,不然最好別用 Platypus。因為它把打包的過程弄得比較複雜,而且它的某些環境參數與 shell 中的不同,故有時執行的結果會跟 Terminal 中的不一樣 ,所以我個人不推薦它。
附註
1. 只要有在 Applescript 寫過 Mac OS 檔案路徑的人,應該能理解為何大家都用 Unix 的 POSIX 檔案路徑 .....
沒有留言:
張貼留言