1

I pasted a long list of commands into Bash, and in the middle of execution, I decided I wanted it to stop. Ctrl+Z and Ctrl+C did nothing. It just continues executing line after line. In the end, the commands required a service to be running, so I stopped that instead using another SSH instance, and the commands errored out one after the other.

If I hadn't been able to stop a service to do that, how would I stop the list from continuing to execute?

mbomb007
  • 113
  • 7
  • 1
    I think it would be different if you started a subshell: `( paste long list of commands here )`. This method requires planning ahead though. – Kamil Maciorowski Dec 07 '21 at 22:44

2 Answers2

1

This is a question with a "Don't do that, then" answer.

It's a bad habit to acquire, try to avoid developing it. If you already have it, try to break it. Otherwise just accept the consequences of what you're doing.

Pasting text into a shell fills the input buffer with that text as if you typed it yourself, and any Ctrl-C or Ctrl-Z keystrokes or whatever else you type into the buffer after that won't be processed until what you've already pasted into the buffer is consumed. It's in the queue and has to wait.

Instead, paste your commands into a text editor, edit it as required, save it to a file, and then execute the script.

Alternatively, if you don't want to save the script in a temporary file for some reason, trigger your shell's command line editor mode, paste the commands into the editor, edit it, then save and exit to have those commands executed. This is effectively a way of avoiding the undesirable consequences of pasting bulk text into a shell.

In bash, the editor mode is called edit-and-execute-command and is invoked with Ctrl-XCtrl-E. It will try to run either $VISUAL, $EDITOR, or emacs (in that order) to edit the current input line - so it's not just useful for copy-pasting, it's also useful for editing lines from history. Some other shells (e.g. zsh) have a similar feature.

cas
  • 1
  • 7
  • 119
  • 185
  • "As if you typed it yourself" may or may not be true. [Bracketed paste](https://unix.stackexchange.com/a/309798/108618) may be enabled and then pasting is certainly not "as if you typed". – Kamil Maciorowski Dec 08 '21 at 11:04
  • Kind-of-true...without looking at the source code I suspect that bash just waits for you to hit enter before stuffing what you pasted back into the readline input buffer - it's certainly not running the input like a script would be run. According to bash's changelog, bracketed paste has been enabled by default since bash 5.1-alpha. The feature was added in 4.4-alpha. B-P doesn't solve the OP's problem, anyway - try pasting in multiple lines of `ls; sleep 5`. ^C or ^Z will kill/suspend the currently running sleep, but the remaining `ls; sleep 5` lines will still be executed. – cas Dec 08 '21 at 11:50
  • And it's still true that pasting a long list of commands directly into a shell is a pretty bad habit to develop, it's still a "Don't do that, then". – cas Dec 08 '21 at 11:50
  • Bracketed paste **does** give you another opportunity to use ^X^E to edit the pasted input before accepting it with enter - and, even better, after you save and exit from editor mode, pressing ^C will kill the entire set of pasted commands. ^Z will suspend whatever's currently running but continue with the next command. It's still a bad idea to copy-paste multiple lines directly into a shell, especially if you're copy pasting from an untrustable source like a web page - see [How can I protect myself from this kind of clipboard abuse?](https://security.stackexchange.com/q/39118) – cas Dec 08 '21 at 12:05
0

I have had some success using Ctrl+S to stop output from bash to the console. This also has the side effect of stopping further commands from being executed. For example, I just typed this

sleep 5; date; sleep 5; date

then hit ENTER, and immediately I hit Ctrl-S. Then, I waited one minute, and hit Ctrl-Q and immediately blindly typed date, and ENTER.

I figured I would be able to tell whether the Ctrl-S had stopped only the output, and date had executed one minute earlier (and I would get two dates very close, and a third one minute apart), or if it had stopped at least the second date, and then I would get one date, and then two very close after a pause of one minute.

I got the second, which proves that Ctrl-S stopped as soon as some output hit it.:

$ sleep 5; date; sleep 5; date
Tue 07 Dec 2021 11:12:19 PM CET
date                                <--- this I typed after Ctrl-Q
Tue 07 Dec 2021 11:13:17 PM CET
$ date                              <--- this is my command echoed
Tue 07 Dec 2021 11:13:17 PM CET
$

Once the bash has been stopped, though, you still have to kill it from a different terminal.

LSerni
  • 4,305
  • 14
  • 20