昨天有提一下 rc 檔的使用情境和功能,簡單來說就是做初始化而已,今天我們要自己實作讀取 ~/.goshrc
,話不多說馬上開始吧!
首先我們要先確定家目錄 ~
底下到底有沒有 .goshrc
這個檔案,如果沒有那就不用讀取他了,直接當作沒這回事
如果 ~/.goshrc
存在的話,那就不斷的讀取裡面的指令並且執行,假如裡面有十行 alias xxx='xxx xxxx'
,那就 逐行執行 直到全部讀完為止
os.UserHomeDir()
UserHomeDir()
是用來取得 目前使用者的家目錄(~
)路徑,以我自己來說因為我的 username 是 larry
,所以我的家目錄就是 /Users/larry
os.Open(filename string) (*File, error)
Open
可以用來開啟一個檔案並且得到一個 File
型別的變數,這個 File
變數之後會被用來讀取檔案的內容
bufio.NewReader(rd io.Reader) *bufio.Reader
bufio.NewReader
在很久之前的 Day3 有用過,他可以用來把輸入源(包括 File
)轉成 bufio.Reader
型別,而 bufio.Reader
型別支援逐行讀取
簡單來說,他跟 os.Open
組合起來就可以逐行讀取檔案
initialize
接下來要實作一個 initialize()
來做初始化,也就是逐行執行 ~/.goshrc
的內容
func initialize() {
// 取得家目錄位置,並開啟 ~/.goshrc
homeDir, _ := os.UserHomeDir()
file, err := os.Open(homeDir + "/.goshrc")
// 如果 ~/.goshrc 不存在
// 那就直接結束這個 function
if err != nil {
return
}
// 把 File 轉成 bufio.Reader 型別
// 為後面的逐行讀取做準備
goshrcReader := bufio.NewReader(file)
// 用一個無窮迴圈不斷進行讀取、執行
for {
// 一次從 ~/.goshrc 裡面讀取一行
// input 可能長得像 "alias gst='git status'"
input, err := goshrcReader.ReadString('\n')
// io.EOF 是檔案結尾(End Of File)的意思
// 如果讀取到檔案結束了,代表已經執行完畢
// 就直接結束 function
if err == io.EOF {
return
}
// 把指令頭尾的空白去除掉
input = strings.TrimSpace(input)
// 執行讀取到的指令
// 譬如說執行 "alias gst='git status'"
executeInput(input)
}
}
接著就是到 main()
的開頭執行 initialize()
,讓 Shell 一啟動就去讀取 ~/.goshrc
func main() {
initialize() // <--- HERE
/* 以下都是之前在 Day3 寫的 */
/* 不斷顯示 prompt、執行使用者輸入的指令 */
stdin := bufio.NewReader(os.Stdin)
for {
showPrompt()
// ...
executeInput(input)
}
}
為了實驗有沒有成功執行 ~/.goshrc
,我在 ~/.goshrc
裡面寫上這些內容,等等看 Shell 在啟動時會不會成功 echo、設定 alias
# ~/.goshrc
echo Hello Larry
alias gst='git status'
alias l='ls -l'
剛進到 Shell 時他就先輸出 Hello Larry
,我下 gst
有成功執行 git status
、which l
也得到正確的 alias,Gosh 果然沒讓我失望 ???
今天的內容跟很久之前的 Day3 很類似,雖然 Day3 是讀取使用者輸入而今天是讀取檔案,但本質上都是從 Reader(資料來源) 進行讀取,所以做法也很相似
如果對今天的內容有什麼問題歡迎在下方留言,沒問題的話就明天見囉