原本以為已經差不多有 Shell 的樣子了,結果剛剛試了一下竟然不能 cd
,這 Shell 真是爛得徹底,竟然連 cd 都不行,這樣也能叫做 Shell 嗎???
各位客倌先別激動,且聽筆者我來娓娓道來
之前在 Day2 跟 Day5 有說過,Shell 收到指令之後會到系統的 PATH
裡面尋找執行檔,接著再啟動一個 Process 來執行它,如下圖
也可以用 which
來看到某個指令的執行檔放在哪裡,像 ls
、ps
跟 mv
都是放在 /bin
裡面
但神奇的事情發生了,用 which cd
去看 cd
執行檔時卻顯示 shell built-in command
,也就是所謂的 Shell 內建指令,意思是他不是一個執行檔,而是 Shell 要自己實作的指令
cd
?cd
指令的目的是要改變目前 Shell 的 Working Directory,但因為 每一個 Process 有自己的 Working Directory(包括 Shell),所以 Shell 沒辦法另外開一個 Process 來幫他自身進行 cd
,而是 Shell 本身收到 cd
指令後要變更自己的資料夾
總而言之,Shell 的 cd
指令沒辦法讓其他 Process 幫忙做,一定得自己做才行
懂了這個觀念之後就來看看怎麼做吧
os.Chdir(dir string)
Chdir
也是一個 System Call,他可以切換目前 Process 的 Working Directory,所以要用它來實作 cd
executeInput
func executeInput(input string) error {
args := strings.Split(input, " ")
if args[0] == "cd" {
// 如果指令是 cd dirname
// 就跑 os.Chdir(dirname)
err := os.Chdir(args[1])
// 並回傳發生的錯誤(例如資料夾不存在)
return err
}
cmd := exec.Command(args[0], args[1:]...)
// ...
}
如果使用者輸入的指令是 cd dirname
,那就使用 os.Chdir
來切換 Working Directory,而不是另外開一個 Process 來跑 cd
,因為 cd
一定要是自己跑
總算是可以正常 cd
囉,ls
的結果也確實是那個資料夾的
其實像 cd
這樣的內建指令還有很多,像是 exit
跟 alias
,只要是改變 Shell 內部狀態的功能都必須是內建指令,因為另外啟動 Process 並不能改變目前 Shell 的狀態
今天的 commit 放在這裡,有什麼問題歡迎在下方提問,沒問題的話就明天見囉~