這一系列原本有很多想做的功能,但因為只有三十天的時間,所以真正實作的幾乎都是比較基本的 Shell 功能,而比較進階的功能就少有著墨
雖然沒時間做,不過我今天會大概說一下那些功能要怎麼做,如果讀者想自己做的話也比較有個方向
Pipe 是我最想做的功能之一,但因為 Signal 我也很想講,想說應該比較多人不知道 Signal 所以最後還是放棄了 Pipe ?
Pipe 的語法是這樣:cmd1 | cmd2,意思是把 cmd1 的 Stdout 接到 cmd2 的 Stdin,就像 把兩條水管接起來 一樣。譬如說 cat 是用來輸出檔案內容,而 wc -l 是用來計算內容有幾行,把它們 組合 起來變成 cat main.go | wc -l 就可以計算 main.go 有幾行

或是 ps aux 是用來看所有 Process,而 grep session 是用來過濾包含 session 的字串,把他們串起來變成 ps aux | grep session 就可以顯示所有名字包含 session 的 Process

要實作這個功能也不會太難:
cmd1 | cmd2 用 strings.Split 切成 ["cmd1", "cmd2"]
cmd.StdoutPipe 跟 cmd.StdinPipe 分別取出 cmd1 的 Stdout 跟 cmd2 的 Stdinio.Copy() 把他們接起來,這樣就完成 Pipe 功能了~在 Linux 裡面有個 && 功能可以串接很多指令,譬如說 cmd1 && cmd2 就會在 cmd1 執行成功之後 緊接著執行 cmd2 指令
像我最近在寫這個 Gosh 專案時就常常需要重新編譯、執行,因為我比較懶一點所以我常常會跑 go build && ./Gosh,這樣就可以一次把編譯跟執行做完~

要實作這個功能還滿簡單的,大致上是:
cmd1 && cmd2 && cmd3 切成 [cmd1, cmd2, cmd3]
大部分 Shell 都有直接執行 .sh 腳本的能力,譬如說我可以寫一個 hello.sh 內容如下
date
echo Hello Larry
接著下 ./hello.sh 執行他,Shell 就會執行我寫的內容

那要做到這件事也滿簡單的,基本上跟 Day20 讀取 ~/.goshrc 是一樣意思,反正就把檔案讀進來、一行一行 丟進之前寫的 execInput 跑,跑完就結束了XD
歷史紀錄包含兩個小功能,第一個是下 history 時會印出完整的指令歷史紀錄,加上 tail -n5 的話就會擷取最近的五筆

另一個則是下 !n 的時候會執行紀錄中編號 n 的指令,以上圖來說,下 !3034 就會執行 vim ~/.zshrc

做法的話也不難:
history:直接把 .gosh_history檔案印出來!n:找到 ~/.gosh_history 的第 n 行並執行就可以了pushd 跟 popd在 Linux 裡面大家應該都很習慣用 cd 來切換資料夾,但其實有一組指令更好用,他們是 pushd 跟 popd
pushd 跟 cd 的效果一樣,不過他會順便把目前資料夾 push 到資料夾的 stack 上,譬如說我原本在家目錄 ~,我 pushd Desktop 後就會切換到桌面,而且會把 ~/Desktop 放到 stack 的最上面(左邊)

再下 pushd repos 就會切換到 ~/Desktop/repos

如果這時我想回到上個資料夾就可以用 popd,他會把目前的資料夾 pop 掉、回到上個資料夾,每次 popd 都會再回到上一個

簡單來說,pushd、popd 這一組指令可以方便的切換到之前所在的資料夾,如果想知道目前 stack 的狀況也可以下 d 看看

今天對於其他功能的做法就講到這邊,其實就算幫 Gosh 加上這些功能也還是離 zsh 很遠XD,不過畢竟 30 天而已能做的很有限,做到這樣我自己覺得已經不錯了~
有問題的話歡迎在下面留言,沒問題的話明天要把 Gosh 發佈到 Homebrew 上,這樣大家就能夠下載我寫的 Shell 囉