把Ruby script變成執行檔(executable)


那些青澀的日子

平常我們在撰寫Ruby script時,大概都是遵循以下模式:

  1. 建立一個hello.rb檔案
  2. 輸入以下內容:
puts "hello world"

3 在command line當中執行:

$ ruby hello.rb

但日積月累下來,我們都慢慢變成資深的Rubist,身為一個專業的Rubist,當然要用一些更方便的作法來執行及管理scripts。

1. 省去ruby指令

首先,每次執行都要在前面加上ruby是很擾人的事情,我們先將它拿掉。

hello.rb當中,加上第一行環境變數:

#!/usr/bin/env ruby
puts "hello world"

接著在該檔案的目錄底下,在Terminal輸入:

$ ls -l hello.rb

接著會出現以下結果:

-rw-r--r--  1 username group  7640 Jun  8 16:58 hello.rb

目前無法對檔案進行「執行」的動作,這時用chmod指令來修改權限,以便直接執行檔案。輸入:

$ chmod 755 hello.rb

再檢查一次權限會變成:

-rwxr-xr-x  1 username group  7640 Jun  8 16:58 hello.rb

訊息上的x代表可以執行這個檔案,至於其他部分這邊就不多談,Linux的權限問題可以參考鳥哥的私房菜

沒有意外的話,我們就可以用以下指令執行同一個檔案,不需要再加上ruby指令:

$ ./hello.rb

一樣會出現原本在script當中寫的hello world

2. 移除結尾的.rb

其實當我們可以直接執行檔案時,只要確保第一行有設定環境變數#!/usr/bin/env ruby,那.rb就可以拿掉。

這邊可以直接執行:

$ mv hello.rb hello
$ ./hello

應該也一樣會出現hello world的結果。

3. 移除路徑

之所以執行時要加上./是因為我們直接執行一個指令時,系統會用$PATH變數來尋找指令位置,除非我們將hello.rb放在$PATH所包含的路徑當中,否則就一定要加上./來代表「從我們目前的路徑執行這個檔案」。

這邊有兩種解決方法:

  1. 自己設定一個資料夾,並將這個資料夾納入$PATH這個系統變數當中,這樣未來所有scripts都放到裡面管理即可。
  2. 把所有script丟到像/usr/local/bin這樣原本預設就在$PATH系統變數當中的資料夾位置。

解法1:移動檔案至系統預設資料夾內

這是比較簡單的作法,直接一行搞定:

$ mv hello /usr/local/bin/hello

不過通常script有一個特性就是活不久,今天可能我們為了一個功能寫了script,但實際上可能只會用到1~2個星期,如果用第一種作法丟到/usr/local/bin當中,裡面有太多的系統預設指令,很容易忘記有這個script的存在。一方面容易重複寫,一方面忘了刪也浪費空間。

解法2:自行管理資料夾

用另一種解法,在自己方便的地方建立一個資料夾:

$ mkdir -p scripts/bin
$ mv hello scripts/bin/hello

接著如果你是用Bash,就找到.bashrc,如果是用zsh,就找到.zshrc,依此類推。檔案裡頭找到系統的PATH變數設定這行,應該是長這樣:

export PATH="/usr/bin:usr/local/bin"

類似這樣的結構,當然中間字串會非常非常的長。

這時我們在尾巴加上剛才設定好的目錄位置,記得在連接點加上冒號(:)並加上完整路徑:

export PATH="/usr/bin:usr/local/bin:/Users/username/scripts/bin"

username是你自己的帳號名稱,如果不清楚加了什麼,可以跟上面原本的內容對照看看。或是如果你有另外的自訂路徑,就加上自己的路徑。

收工!

不管用哪個解法,完成以後不管在任何地方直接執行:

$ hello

就會出現我們在script當中所寫的hello world了!

延伸閱讀

鳥哥的私房菜:關於檔案權限

Making a Ruby Script Executable