I'm having some troubles reading from piped input, and then prompting a user for a further question afterwards. Is this possible to do?
I've created a simplified version of the program here.
I want the user to be able to pipe input in to the program instead of being prompted for it. However, I still want to prompt them with a second question if they don't provide a specific flag in a CLI program I'm writing.
To avoid any prompts, the user could pass in -y (not shown in the program below) along with piping in the text input to skip the "are you sure?" prompt.
package main
import (
"fmt"
"os"
"github.com/AlecAivazis/survey/v2"
)
func main() {
value := ""
isPiped, err := isPipedInput()
if err != nil {
panic(err)
}
if isPiped {
_, err = fmt.Scanf("%s", &value)
if err != nil {
panic(err)
}
if value == "" {
panic(fmt.Errorf("must be greater than 0"))
}
} else {
err = survey.AskOne(&survey.Input{Message: "Enter value followed by [Enter]:"}, &value)
if err != nil {
panic(err)
}
if value == "" {
panic(fmt.Errorf("must be greater than 0"))
}
}
shouldProceed := false
err = survey.AskOne(&survey.Confirm{Message: "Are you sure?"}, &shouldProceed)
if err != nil {
panic(err)
}
if shouldProceed {
fmt.Println("Proceeding!", value)
} else {
fmt.Println("Not proceeding...", value)
}
}
func isPipedInput() (bool, error) {
fi, err := os.Stdin.Stat()
if err != nil {
return false, err
}
return (fi.Mode() & os.ModeCharDevice) == 0, nil
}
To build:
go build -o main
First use-case that works as expected:
./main
? Enter value followed by [Enter]: foo
? Are you sure? Yes
Proceeding! foo
Second use case that does not work:
echo "foo" | ./main
? Are you sure? (y/N) ^[[23;256Rpanic: EOF
goroutine 1 [running]:
main.main()
/main.go:40 +0x2b0
^[[8;23R%