iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
1
Software Development

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

Day06-執行指令(二)

今日目標

昨天看似已經完成執行指令,其實不然,昨天下的指令 lspsvim 都是沒有參數的,如果加上參數就會發生錯誤,到底為什麼會這樣呢???

分析原因

當我下指令 ls -la 他出現這個錯誤,意思是 他找不到 ls -la 這個執行檔

因為 根本就沒有 ls -la 這個執行檔-lals 指令的參數,所以當使用者輸入 ls -la,跑到 exec.Command("ls -la") 並執行時會找不到 ls -la 這個執行檔

解決方法

讓我們來看看 exec.Command 的 signature

func Command(name string, arg ...string) *Cmd

他除了第一個參數 name 之外後面還可以放很多個 arg,所以如果要執行 有參數的指令 要這樣寫

// ls -la
exec.Command("ls", "-la")

// ls -l -a
exec.Command("ls", "-l", "-a")

把參數依序放在後面,這樣 Go 才會正確的把參數傳給指令

實作

會用到的 function

  • strings.Split

    之前有提過 strings 是專門在處理字串的 package,其中的 Split 可以分割字串

    // 以空白字元做為 Separator 把字串分割成 Array
    // ["ls", "-l", "-a"]
    strings.Split("ls -l -a", " ")
    
    
  • exec.Command

    這個在昨天介紹過了,只不過這次要先把參數切割好,再放進去正確的位置

execInput

func executeInput(input string) error {
    // 把使用者的輸入切割成 Array
    // "ps aux" -> ["ps", "aux"]
    args := strings.Split(input, " ")
    
    // args[0] 是指令名,放在第一個位置
    // args[1:]... 是把其他參數依序填入裡面
    // ["ls", "-l", "-a"] 即 exec.Command("ls", "-l", "-a")
    cmd := exec.Command(args[0], args[1:]...)

    // ...
	
    err := cmd.Run()
    return err
}

Demo

現在不管是什麼指令都可以正常執行囉~

ls -la

ps au

top

更換預設的 Shell

因為今天還有點時間,而且目前的 Shell 也已經到了堪用的程度,所以來說說怎麼切換預設的 Shell

跟前幾天講到的 PATH 很類似,系統裡面有一個變數叫做 SHELL,只要把他 echo 出來就知道你目前用的是什麼 Shell,像我現在用的就是 zsh,執行檔放在 /bin/zsh

如果想要換成自己的 Shell 首先要知道 Shell 的路徑,像我自己編譯出來的 Shell 在 /Users/larry/Desktop/repos/Gosh/Gosh,那就要先到 /etc/shells 這個檔案裡面填上自己 Shell 的路徑,這樣系統才知道這個檔案是一個 Shell,否則他不會讓你換

接著就是下指令 chsh -s <SHELL PATH>,打完密碼再重開終端機就可以使用自己寫的 Shell 囉

可以用自己寫的 Shell 來工作好興奮啊~~但這個 Shell 未免也太簡陋了吧,沒有自動補全功能就算了,連目前路徑都還要自己下 pwd 才能知道,還是趕快下 chsh -s /bin/zsh 逃回 zsh 舒適圈

小結

以上就是今天的內容,commit 放在這裡,在未來的很多很多天會繼續改善這個 Shell,如果有什麼問題歡迎在下方留言提問,我都會盡力回答哦~


上一篇
Day05-執行指令(一)
下一篇
Day07-Prompt 大改造(一)
系列文
Gosh!原來用 Go 寫一個 Unix Shell 這麼簡單30

尚未有邦友留言

立即登入留言