我們在昨天已經想好一套實作 Redirect Stdin 的方法,大致上可以分成這幾個步驟:
data
檔案data
檔案func executeInput(input string) error {
// ...
args := parseArgs(input)
// ...
// 先設好預設的 inputStream
// 預設是從終端機進行讀取
inputStream := os.Stdin
// 如果 args 有大於兩個元素,譬如說 ["python", "<", "data"]
// 而且倒數第二個(len(args)-2)是 "<"
// 那就需要重新導向 Stdin
if len(args) > 2 && args[len(args)-2] == "<" {
// 檔案名稱是最後一個參數
// 這邊的 filename = "data"
filename := args[len(args)-1]
// 1. 用昨天講到的 Open 嘗試開啟檔案
file, err := os.Open(filename)
// 2. 如果發生錯誤的話(檔案不存在)就回傳錯誤
if err != nil {
return err
}
// 3. 檔案存在的話就把 inputStream 設為 file 檔案
inputStream = file
// 4. 執行 python 指令
// 因為結尾的 < data 不是 python 的參數
// 所以把最後兩個參數刪掉,只保留前面的 python
// 此時的 args = ["python"]
args = args[:len(args)-2]
}
cmd := exec.Command(args[0], args[1:]...)
// 把 Stdin 來源設為 inputStream
// 如果沒有經過 Redirect,那 inputStream 就是終端機
// 如果有經過 Redirect,則 inputStream 會是那個檔案
cmd.Stdin = inputStream
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
return err
}
因為時間不多所以今天只實作了 Redirect Stdin,但其實 Redirect Stdout 也是差不多的做法,大致上就是 檔案開起來、資料寫進去,有興趣可以自己試試看XD
今天應該是寫最多扣的一天,跟之前一樣有問題歡迎在下方提問,沒問題的話明天就要進入 Signal 的部分了,這部分比較難,各位看倌要有點心理準備哦~