不知不覺就來到第十天了,今明兩天要來談談怎麼在 Shell 中存取(set and get)環境變數,之前只有簡單帶過,今天來認真介紹一下
在 Unix Like 系統中,每個 Process 都有自己的環境變數,而且環境變數會傳給自己的 Child Process,所以由 Shell 產生出來的 Child Process 也會繼承到 Shell 的環境變數
在 Shell 中想看某個變數值可以下指令 echo $VAR
或是 echo ${VAR}
,後者可以再接其他字串譬如說 echo ${SHELL}HelloWorld
如果想看目前環境中的所有變數可以下 env
,常見的 PWD
、SHELL
跟 PATH
都在裡面
目前 Gosh 還沒有取得環境變數的功能,因為它不知道 $SHELL
是一個環境變數,只是很單純的輸出 $SHELL
字串(好笨的 Shell ?)
若要讓 Gosh 成功輸出環境變數必須在 Shell 裡面替換掉字串才行
讀取環境變數也是個 System Call,但 ExpandEnv
已經把 System Call 包裝好了,他可以直接把字串中的 $VAR
跟 ${VAR}
替換成環境變數,譬如說把 echo ${USER}
展開成 echo larry
executeInput
func executeInput(input string) error {
// 把 input 裡面的環境變數展開
// 如果指令是 echo ${USER}_is_smart
// 展開後就會變成 echo larry_is_smart
input = os.ExpandEnv(input)
args := strings.Split(input, " ")
// ...
err := cmd.Run()
return err
}
實作起來超簡單,因為 Go 已經把很多雜事都處理好,不然原本要先自己取得變數再替換 $VAR
跟 ${VAR}
在 Gosh 中輸出 SHELL
、PWD
跟 USER
今天的內容很簡單,就只是把指令中的環境變數都展開來,程式碼放在這裡,有什麼問題歡迎在下面提問(今天這麼簡單應該不會有吧XD),沒問題的話明天就來實作存取環境變數中 存 的部分
對了~有個小小的問題
為什麼在讀std的時候不用這個方法呢?
stdin := bufio.NewReader(os.Stdin)
fmt.Println(">")
input, perf, err := stdin.ReadLine()
問得很好XD,我當初也想了很久到底要用哪個,但後來看到 ReadLine 的說明裡面有寫到
If the line was too long for the buffer then isPrefix is set and the beginning of the line is returned. The rest of the line will be returned from future calls.
意思是說他不保證可以讀取到整行,如果沒有讀取到完整的一行,那就要再 call 一次 ReadLine
拿到後半段
而 ReadString 的說明是
ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter.
意思是 ReadString('\n')
會一直往後讀直到 \n
出現,可以保證讀取到完整的一行,所以就果斷用 ReadString
了XD