2 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
因此,您需要來自 Stdin(管道)和用戶 Stdin(鍵盤)的并發(fā)輸入:
我認(rèn)為您的答案是 cat 命令,請參閱:如何將初始輸入通過管道傳輸?shù)竭M(jìn)程中,然后該進(jìn)程將是交互式的?
和:https://en.wikipedia.org/wiki/Cat_(Unix)
請參閱:如何在 Go 中通過管道傳輸多個(gè)命令?
并進(jìn)行進(jìn)程間通信
有 3 件事需要注意:
首先:檢查所有錯(cuò)誤是一個(gè)好習(xí)慣:
在您的情況下:
n, err := fmt.Scanln(&response)
第二:
您正在使用遞歸調(diào)用(Tail Call),這里沒有必要。
用簡單的 for 循環(huán)替換它并查看: Go
3 中的尾調(diào)用優(yōu)化:
最后但并非最不重要的一點(diǎn):如果輸入錯(cuò)誤,您的代碼將永遠(yuǎn)循環(huán)(如果編譯器無法優(yōu)化尾調(diào)用,則消耗堆棧)!
最好限制在 3 個(gè)。
例如:
package main
import "fmt"
import "strings"
type Input int
const (
Timeout Input = iota
Yes
No
Abort
BadInput
)
func userInput(msg string) Input {
var input string
for i := 0; i < 3; i++ {
fmt.Println(msg)
n, err := fmt.Scanln(&input)
if n > 0 {
switch strings.ToLower(input) {
case "y":
return Yes
case "n":
return No
case "a":
return Abort
}
}
if err != nil {
return BadInput // or panic(err)
}
}
return Timeout
}
func main() {
ans := userInput("Please type Yes,No or Abort and then press enter [y/n/a]: ")
fmt.Println(ans)
switch ans {
case Yes:
fmt.Println("Yes") // do some job
//...
}
}
編輯:使用這個(gè)簡單的“y/n”,您無需檢查它是否是管道。
即使是帶有一個(gè)字節(jié)切片的簡單 std Read 也很好:
os.Stdin.Read(b1)
查看我的管道示例:https ://stackoverflow.com/a/37334984/6169399
但如果您的標(biāo)準(zhǔn)輸入是管道,您可以使用:
bytes, err := ioutil.ReadAll(os.Stdin)
一次讀取所有管道數(shù)據(jù)。但要小心處理錯(cuò)誤。您可以檢查標(biāo)準(zhǔn)輸入是否與終端或管道相關(guān)聯(lián),然后使用適當(dāng)?shù)拇a。
檢測它的簡單方法是否是管道:
package main
import (
"fmt"
"os"
)
func main() {
info, err := os.Stdin.Stat()
if err != nil {
fmt.Println("not a pipe")
} else {
fmt.Println("pipe name=", info.Name(), "pipe size=", info.Size())
}
}
全部在一個(gè)示例代碼中:
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
type Input int
const (
Timeout Input = iota
Yes
No
Abort
BadInput
)
func userInput(msg string) Input {
var input string
for i := 0; i < 3; i++ {
fmt.Println(msg)
n, err := fmt.Scanln(&input)
if n > 0 {
switch strings.ToLower(input) {
case "y":
return Yes
case "n":
return No
case "a":
return Abort
}
}
if err != nil {
return BadInput // or panic(err)
}
}
return Timeout
}
func main() {
info, err := os.Stdin.Stat()
if err != nil {
//fmt.Println("not a pipe")
ans := userInput("Please type Yes,No or Abort and then press enter [y/n/a]: ")
fmt.Println(ans)
switch ans {
case Yes:
fmt.Println("Yes") // do some job
//...
}
} else {
fmt.Println("pipe name=", info.Name(), "pipe size=", info.Size())
bytes, err := ioutil.ReadAll(os.Stdin)
fmt.Println(string(bytes), err) //do some jobe with bytes
}
}

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超4個(gè)贊
您可以使用os.ModeCharDevice:
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
// piped
input, _ := ioutil.ReadAll(os.Stdin)
} else {
// not piped, do whatever, like fmt.Scanln()
}
- 2 回答
- 0 關(guān)注
- 174 瀏覽
添加回答
舉報(bào)