connect stdin of external commands to the terminal
Without Stdin, commands read from /dev/null, so interactive programs like 'sudo su -', vim or ssh got EOF right away. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2b8f06ea6d
commit
139896a593
2 files changed
+37
-2
No files matched your search
@@ -760,9 +760,13 @@ Features:
|
|||||||
// Prepare the command to execute.
|
// Prepare the command to execute.
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
|
||||||
// Set the correct output device.
|
// Connect the command to the terminal. Without Stdin the command would
|
||||||
cmd.Stderr = os.Stderr
|
// read from /dev/null, so interactive programs (su, vim, ssh, ...) would
|
||||||
|
// get EOF right away. readline only reads from stdin while a line is
|
||||||
|
// being edited, so it does not steal input from the command.
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
// Execute the command return the error.
|
// Execute the command return the error.
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
|
|||||||
@@ -1221,3 +1221,34 @@ func TestShell_SIGINTKillsOnlyChild(t *testing.T) {
|
|||||||
t.Errorf("child was not interrupted (took %v)", elapsed)
|
t.Errorf("child was not interrupted (took %v)", elapsed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExecInput_PassesStdin(t *testing.T) {
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
origStdin := os.Stdin
|
||||||
|
os.Stdin = r
|
||||||
|
defer func() {
|
||||||
|
os.Stdin = origStdin
|
||||||
|
r.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := w.WriteString("hello\n"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
out := filepath.Join(t.TempDir(), "out")
|
||||||
|
t.Setenv("GOSH_TEST_OUT", out)
|
||||||
|
if err := execInput(`sh -c 'read x; printf %s "$x" > "$GOSH_TEST_OUT"'`); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
got, err := os.ReadFile(out)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if string(got) != "hello" {
|
||||||
|
t.Errorf("command read %q from stdin, want %q", got, "hello")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user