From 4a4a3dd9d16ba58bafdbef540f864edb99664df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sun, 30 Nov 2025 10:10:35 +0100 Subject: [PATCH 1/2] Check tty flag also for the shell command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- cmd/limactl/shell.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/limactl/shell.go b/cmd/limactl/shell.go index 017aa1f579b..4af391f282f 100644 --- a/cmd/limactl/shell.go +++ b/cmd/limactl/shell.go @@ -70,6 +70,10 @@ func newShellCommand() *cobra.Command { func shellAction(cmd *cobra.Command, args []string) error { ctx := cmd.Context() flags := cmd.Flags() + tty, err := flags.GetBool("tty") + if err != nil { + return err + } // simulate the behavior of double dash newArg := []string{} if len(args) >= 2 && args[1] == "--" { @@ -100,8 +104,8 @@ func shellAction(cmd *cobra.Command, args []string) error { return err } - if !flags.Changed("start") { - startNow, err = askWhetherToStart() + if tty && !flags.Changed("start") { + startNow, err = askWhetherToStart(cmd) if err != nil { return err } From f6b6326dd180e728e2437b2b8782be87f414b994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sun, 30 Nov 2025 10:11:11 +0100 Subject: [PATCH 2/2] Check that input is a tty before using it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current UI library will crash, if trying to read input from something that is not a terminal (a TTY). Signed-off-by: Anders F Björklund --- cmd/limactl/clone.go | 2 +- cmd/limactl/edit.go | 12 ++++++++---- pkg/uiutil/uiutil.go | 11 +++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/limactl/clone.go b/cmd/limactl/clone.go index 06a95f68c15..9afe6f9ce42 100644 --- a/cmd/limactl/clone.go +++ b/cmd/limactl/clone.go @@ -121,7 +121,7 @@ func cloneOrRenameAction(cmd *cobra.Command, args []string) error { } if tty && !flags.Changed("start") { - start, err = askWhetherToStart() + start, err = askWhetherToStart(cmd) if err != nil { return err } diff --git a/cmd/limactl/edit.go b/cmd/limactl/edit.go index f2212fe89d3..b13fea4b919 100644 --- a/cmd/limactl/edit.go +++ b/cmd/limactl/edit.go @@ -153,7 +153,7 @@ func editAction(cmd *cobra.Command, args []string) error { } if tty && !flags.Changed("start") { - start, err = askWhetherToStart() + start, err = askWhetherToStart(cmd) if err != nil { return err } @@ -180,9 +180,13 @@ func editAction(cmd *cobra.Command, args []string) error { return instance.Start(ctx, inst, false, false) } -func askWhetherToStart() (bool, error) { - message := "Do you want to start the instance now? " - return uiutil.Confirm(message, true) +func askWhetherToStart(cmd *cobra.Command) (bool, error) { + isTTY := uiutil.InputIsTTY(cmd.InOrStdin()) + if isTTY { + message := "Do you want to start the instance now? " + return uiutil.Confirm(message, true) + } + return false, nil } func editBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { diff --git a/pkg/uiutil/uiutil.go b/pkg/uiutil/uiutil.go index 91e64ceb419..77016da2556 100644 --- a/pkg/uiutil/uiutil.go +++ b/pkg/uiutil/uiutil.go @@ -41,6 +41,17 @@ func Select(message string, options []string) (int, error) { return ans, nil } +// InputIsTTY returns true if reader is coming from stdin, and stdin is a terminal device, +// not a regular file, stream, or pipe etc. +func InputIsTTY(reader io.Reader) bool { + // This setting is needed so we can write integration tests for the TTY input. + // It is probably not useful otherwise. + if os.Getenv("_LIMA_INPUT_IS_TTY") != "" { + return true + } + return reader == os.Stdin && (isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd())) +} + // OutputIsTTY returns true if writer is going to stdout, and stdout is a terminal device, // not a regular file, stream, or pipe etc. func OutputIsTTY(writer io.Writer) bool {