2012年6月29日 星期五

自製的 sh 檔不能執行?!


這篇文章算是一個小問題的探討,而且我發現這個問題居然從 Mac OSX 10.4 到現在的 Mac OSX 10.7 都還沒有解決?! (應該在更早的 Mac OSX 裡就存在了,但我沒有更老的系統可以測試) 什麼問題呢?請往下看。

我在之前的文章中曾分享過不少用 Applescript 寫的小程式或是工作流程 (workflow),但有時候我也會使用另一種腳本語言 -- shell script 來寫些小東西,比如說把幾個常用的 shell command (也就是大家常說的 "終端機指令") 打包起來以便隨時取用,一般來說作法有兩種:

1. 將指令製作成純文字檔
作法很簡單,就是將你要打包的指令儲存成任意的純文字檔 (可使用任何文字編輯器) [1],然後用 "sh" 指令執行它 (以放在桌面的 test.txt 檔為例):

sh ~/Desktop/test.txt

"sh" 這個指令能夠接受 "標準輸入" (STDIN) 或 "純文字檔" 的輸入,以執行其內的 shell command,雖然這種作法沒什麼不好,但比較少人用。

2. 將指令製作成 sh 執行檔
這種作法相對地比較常見,因為它能實際做出一個客製化的小程式。作法也很簡單,只要將內含指令之純文字檔的副檔名改成 ".sh",再賦予其 "執行" (executable) 權限即可 (以下同樣以放在桌面的 test.txt 檔為例):

mv ~/Desktop/test.txt ~/Desktop/test.sh 
chmod +x ~/Desktop/test.sh

(mv 那一行只是為了改副檔名,基本上在檔名裡直接修改即可) 完成 sh 檔後,可以直接將其拖拉放到終端機視窗中執行,也可以將其置入系統預設的 shell command 路徑中,往後要使用這支程式的時候只要鍵入檔名即可,不用再次輸入路徑。至於何謂 "系統預設的 shell command 路徑" 呢?它指的是 shell command 那些小程式在檔案系統中的所在地,比如說 mv、ls .... 等指令其實各自都是一個小程式,而查詢這些路徑的指令如下:

echo $PATH

對 shell 比較熟的朋友應該知道上述指令就是用 echo 來讀取環境變數 PATH 的內容,不過細節的東西就不在這裡說了,而上圖所呈現的結果是我的 shell command 路徑,中間以 ":" 隔開 (第一個路徑並不是 Mac OSX 的預設值,是因為我裝了 Python 2.7 才加上去的) [2]。

不過呢,有時候會發生奇怪的事情:


上圖是我最近遇到的一個怪現象 (這也顯示出我很少寫 shell script ..... 囧),自製的 sh 檔居然無法執行?!但我以同樣的步驟在 Linux 上進行就完全沒問題 ..... 如果你也看過相同的錯誤訊息,請先別急著放棄,試試小弟我提供的解法吧~


解法?其實也沒啥好解的啦,原因很簡單,就是 Mac OSX 內建的 shell 不支援 UTF-16 編碼的文字指令,這一點到了 Mac OSX Lion 還是一樣。所以,如果你自製或下載來的 shell script 檔無法執行,不彷如上圖以 "文字編輯" (TextEdit.app) 另存成其他編碼試試看,目前上圖的名單中只有 UTF-16 不行,其他都 OK (不過還是建議用萬國碼 UTF-8 啦~) [3]。


附註
1. 一定要是 "純文字檔",光是檔案內容是 "純文字" 可不行~
2. 有人比較建議在家目錄下新增一個純文字檔 ".profile" (注意最前面有個點,這是個隱藏檔),然後把指令路徑寫進去,以達到一樣的效果。這樣做的好處是可以不用動到系統資料夾,比較安全一點,要怎麼做就看個人的喜好了。
3. UTF-16 是萬國碼 (Unicode) 的實作方式之一,"16" 意指 16 位元,也間接地表示這種編碼能呈現更多奇怪的字元或符號,不過 Mac OSX 的 shell 還沒支援這種高檔的編碼就是 ....

沒有留言:

張貼留言