iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
1
Software Development

Gosh!原來用 Go 寫一個 Unix Shell 這麼簡單系列 第 20

Day20-.goshrc 設定檔(二)

前言

昨天有提一下 rc 檔的使用情境和功能,簡單來說就是做初始化而已,今天我們要自己實作讀取 ~/.goshrc,話不多說馬上開始吧!

程式流程

開啟檔案

首先我們要先確定家目錄 ~ 底下到底有沒有 .goshrc 這個檔案,如果沒有那就不用讀取他了,直接當作沒這回事

逐行讀取、執行

如果 ~/.goshrc 存在的話,那就不斷的讀取裡面的指令並且執行,假如裡面有十行 alias xxx='xxx xxxx',那就 逐行執行 直到全部讀完為止

實作

會用到的 function

  • 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)
    }
}

Demo

為了實驗有沒有成功執行 ~/.goshrc,我在 ~/.goshrc 裡面寫上這些內容,等等看 Shell 在啟動時會不會成功 echo、設定 alias

# ~/.goshrc
echo Hello Larry
alias gst='git status'
alias l='ls -l'

剛進到 Shell 時他就先輸出 Hello Larry,我下 gst 有成功執行 git statuswhich l 也得到正確的 alias,Gosh 果然沒讓我失望 ???

小結

View commit on Github

今天的內容跟很久之前的 Day3 很類似,雖然 Day3 是讀取使用者輸入而今天是讀取檔案,但本質上都是從 Reader(資料來源) 進行讀取,所以做法也很相似

如果對今天的內容有什麼問題歡迎在下方留言,沒問題的話就明天見囉


上一篇
Day19-.goshrc 設定檔(一)
下一篇
Day21-Redirect Stdin(一)
系列文
Gosh!原來用 Go 寫一個 Unix Shell 這麼簡單30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言