這一系列原本有很多想做的功能,但因為只有三十天的時間,所以真正實作的幾乎都是比較基本的 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 囉