diff --git a/cmd/tailscale/cli/network-lock.go b/cmd/tailscale/cli/network-lock.go index ec3b01ad6..9b2f6fbdb 100644 --- a/cmd/tailscale/cli/network-lock.go +++ b/cmd/tailscale/cli/network-lock.go @@ -384,7 +384,7 @@ Removal of a signing key(s) without resigning nodes (--re-sign=false) will cause any nodes signed by the the given key(s) to be locked out of the Tailscale network. Proceed with caution. `) - if !prompt.YesNo("Are you sure you want to remove the signing key(s)?") { + if !prompt.YesNo("Are you sure you want to remove the signing key(s)?", true) { fmt.Printf("aborting removal of signing key(s)\n") os.Exit(0) } diff --git a/cmd/tailscale/cli/risks.go b/cmd/tailscale/cli/risks.go index dfde87f64..d4572842b 100644 --- a/cmd/tailscale/cli/risks.go +++ b/cmd/tailscale/cli/risks.go @@ -66,7 +66,7 @@ func presentRiskToUser(riskType, riskMessage, acceptedRisks string) error { outln(riskMessage) printf("To skip this warning, use --accept-risk=%s\n", riskType) - if prompt.YesNo("Continue?") { + if prompt.YesNo("Continue?", false) { return nil } diff --git a/cmd/tailscale/cli/serve_v2.go b/cmd/tailscale/cli/serve_v2.go index 058d80649..8831db2a9 100644 --- a/cmd/tailscale/cli/serve_v2.go +++ b/cmd/tailscale/cli/serve_v2.go @@ -1086,7 +1086,7 @@ func (e *serveEnv) removeWebServe(sc *ipn.ServeConfig, dnsName string, srvPort u if len(mounts) > 1 { msg := fmt.Sprintf("Are you sure you want to delete %d handlers under port %s?", len(mounts), portStr) - if !e.yes && !prompt.YesNo(msg) { + if !e.yes && !prompt.YesNo(msg, true) { return nil } } diff --git a/cmd/tailscale/cli/update.go b/cmd/tailscale/cli/update.go index 7c0269f6a..7eb0dccac 100644 --- a/cmd/tailscale/cli/update.go +++ b/cmd/tailscale/cli/update.go @@ -87,5 +87,5 @@ func confirmUpdate(ver string) bool { } msg := fmt.Sprintf("This will update Tailscale from %v to %v. Continue?", version.Short(), ver) - return prompt.YesNo(msg) + return prompt.YesNo(msg, true) } diff --git a/util/prompt/prompt.go b/util/prompt/prompt.go index 4e589ceb3..a6d86fb48 100644 --- a/util/prompt/prompt.go +++ b/util/prompt/prompt.go @@ -6,19 +6,34 @@ package prompt import ( "fmt" + "os" "strings" + + "github.com/mattn/go-isatty" ) // YesNo takes a question and prompts the user to answer the // question with a yes or no. It appends a [y/n] to the message. -func YesNo(msg string) bool { - fmt.Print(msg + " [y/n] ") +// +// If there is no TTY on both Stdin and Stdout, assume that we're in a script +// and return the dflt result. +func YesNo(msg string, dflt bool) bool { + if !(isatty.IsTerminal(os.Stdin.Fd()) && isatty.IsTerminal(os.Stdout.Fd())) { + return dflt + } + if dflt { + fmt.Print(msg + " [Y/n] ") + } else { + fmt.Print(msg + " [y/N] ") + } var resp string fmt.Scanln(&resp) resp = strings.ToLower(resp) switch resp { case "y", "yes", "sure": return true + case "": + return dflt } return false }