RunInteractiveShell runs a shellcommand interactively
(input string, wait bool, getOutput bool)
| 70 | |
| 71 | // RunInteractiveShell runs a shellcommand interactively |
| 72 | func RunInteractiveShell(input string, wait bool, getOutput bool) (string, error) { |
| 73 | args, err := shellquote.Split(input) |
| 74 | if err != nil { |
| 75 | return "", err |
| 76 | } |
| 77 | if len(args) == 0 { |
| 78 | return "", errors.New("No arguments") |
| 79 | } |
| 80 | inputCmd := args[0] |
| 81 | |
| 82 | // Shut down the screen because we're going to interact directly with the shell |
| 83 | screenb := screen.TempFini() |
| 84 | |
| 85 | args = args[1:] |
| 86 | |
| 87 | // Set up everything for the command |
| 88 | outputBytes := &bytes.Buffer{} |
| 89 | cmd := exec.Command(inputCmd, args...) |
| 90 | cmd.Stdin = os.Stdin |
| 91 | if getOutput { |
| 92 | cmd.Stdout = io.MultiWriter(os.Stdout, outputBytes) |
| 93 | } else { |
| 94 | cmd.Stdout = os.Stdout |
| 95 | } |
| 96 | cmd.Stderr = os.Stderr |
| 97 | |
| 98 | // This is a trap for Ctrl-C so that it doesn't kill micro |
| 99 | // micro is killed if the signal is ignored only on Windows, so it is |
| 100 | // received |
| 101 | c := make(chan os.Signal, 1) |
| 102 | signal.Reset(os.Interrupt) |
| 103 | signal.Notify(c, os.Interrupt) |
| 104 | err = cmd.Start() |
| 105 | if err == nil { |
| 106 | err = cmd.Wait() |
| 107 | if wait { |
| 108 | // This is just so we don't return right away and let the user press enter to return |
| 109 | screen.TermMessage("") |
| 110 | } |
| 111 | } else { |
| 112 | screen.TermMessage(err) |
| 113 | } |
| 114 | |
| 115 | output := outputBytes.String() |
| 116 | |
| 117 | // Start the screen back up |
| 118 | screen.TempStart(screenb) |
| 119 | |
| 120 | signal.Notify(util.Sigterm, os.Interrupt) |
| 121 | signal.Stop(c) |
| 122 | |
| 123 | return output, err |
| 124 | } |
| 125 | |
| 126 | // UserCommand runs the shell command |
| 127 | // The openTerm argument specifies whether a terminal should be opened (for viewing output |