3

I have 2 CentOS systems which I connect to via ssh. On one of them if I paste multiple commands from the clipboard, it executes them all, unless there's a sudo command in there. If there is, it just does it, and skips all other commands. Eg.:

$ echo aa
sudo echo bb
echo cc

Results:

aa
bb

Doesn't matter which sudo command, doesn't matter how many commands before or after. bind -v's enable-bracketed-paste is set to off

Another example:

$ sudo echo dd ;\
echo ee
echo ff

Result:

dd
ee

Other CentOS, it doesn't happen. Why does it happen and how to fix w/o modifying the pasted command?

EDIT: discovered that on ksh it does not happen. I can't install other shells to test.

5
  • Which terminal emulator are you using? Commented May 25, 2022 at 14:12
  • xterm on both systems. I'm using a windows PuTTY or MobaXterm to connect. New discovery - using ksh, it doesn't happen Commented May 26, 2022 at 8:10
  • Does this answer your question? Make a trailing newline execute a command when pasted into the shell Commented May 26, 2022 at 8:25
  • Unfortunately, no. enable-bracketed-paste is already Off Commented May 26, 2022 at 14:02
  • I'm seeing the same behaviour on Bash 5.1.16, Readline 8.01, but only when using Screen (v4.09). It does not happen in a non-screen shell or ssh session, and the behaviour is the same regardless of the enable-bracketed-paste setting. Commented Oct 27, 2022 at 10:17

3 Answers 3

2
+50

This looks like a case of standard input inadvertent consuming.

Anything you paste in an interactive session is standard input data available to the command running in the foreground at that moment, and is normally shared by (and available to) all and any command you may be running in sequence, however quickly (or slowly) you may be able to type/paste. Each of the commands has its chance to consume part or all of the standard input data that happens to be available at the time of its execution.

sudo is indeed one of those commands that will actively eat up all its standard input if it is configured to do so, which may well be the case for security reasons especially in enterprise setups. If this is the case for you, sudo is consuming whatever text (i.e. the subsequent commands) you have pasted in.

If you are allowed to see the /etc/sudoers* file(s) of the host you're experiencing that behavior on, check them whether they possibly have a Defaults line setting either use_pty or log_input (or even both), for ALL, or perhaps for your account or group, or even just for that exact command you're running through sudo. As a matter of fact, it may actually even be some other system-wide plugin set in /etc/sudo.conf, if the system administrator has been so inclined (unlikely, but possible).


Anyhow, you should be able to work-around that behavior by simply wrapping your paste within a sub-shell:

Just start by typing an open parentheses ( at the regular prompt of whatever shell you're using, then press Enter. You'll see the so-called "PS2" (aka "more input needed") prompt, which typically is > , where you can keep typing commands at will and, of course, also pasting them from your clipboard just as they are. These commands will not be run immediately, they will rather be "enqueued" in the sub-shell started by the open parentheses until you end it explicitly. When you're done typing/pasting, finish by typing the close parentheses ) and again Enter, which ends the sub-shell.

Only at that point will your pasted commands finally run, without being "eaten up" by any one of them in midst (sudo or else) that might be consuming standard input as per its normal (or special) behavior. This is because all your relevant standard input (i.e. your pasting) will have already been consumed by the "enqueuing" sub-shell and thus sudo will have nothing to "eat up".


Note finally that in your case enable-bracketed-paste on would be your friend, as that essentially makes bash detect pasted text, differentiating it from typed text, aided by the terminal emulator (as long as the terminal emulator does offer such feature).

As to the reason why ksh seems to be working "correctly", I haven't delved into its internals but, at a first glance of strace-ing it, it appears to be reading bufferfuls of standard input, probably tokenizing it into single commands to run one by one, as opposed to reading-and-executing standard input in the typical streamlined fashion.

As to screen disregarding enable-bracketed-paste on altogether, I'm not an avid user of screen myself, but I can tell as much: it's clearly a very "rich" piece of software terminal-wise, it may act as a terminal emulator itself, and as such it might interfere with (e.g. ignore and strip away) the escape-codes that bash sends/receives to/from the terminal emulator for the bracketed-paste feature.

2
  • 1
    (1) "If you are allowed to see the /etc/sudoers* file(s) …" – Even if not, sudo -l or sudo -ll may reveal something. (2) In my Kubuntu I'm able to replicate the problem by manipulating use_pty in sudoers and enable-bracketed-paste in readline in Bash. I cannot tell if your diagnosis is exactly what happens in the OP's case, but I think it certainly is a possibility. +1 from me. Commented Mar 1, 2023 at 5:20
  • Yes, thank you, I had forgotten about those two user-oriented options
    – LL3
    Commented Mar 1, 2023 at 21:38
0

This behavior may be related to how the shell is interpreting the command sequence when you paste it into the terminal. One possible explanation is that the shell on the system where this behavior is observed is interpreting the entire command sequence as a single line, and the sudo command is causing the shell to exit before executing the rest of the commands.

To avoid modifying the pasted command and work around this issue, you could try a couple of things:

  1. Use a different shell: As you mentioned, the issue is not observed when using the Korn shell (ksh). You could try using a different shell, such as Bash or Zsh, to see if the behavior changes.

  2. Use a subshell: You can group the commands in a subshell, and then use sudo to execute the subshell. This would ensure that all the commands are executed within the subshell, regardless of whether the sudo command exits the shell. For example:

$ (echo aa ; echo bb ; echo cc)
$ sudo sh -c '(echo aa ; echo bb ; echo cc)'

Note that the subshell approach may not work in all cases, especially if the pasted commands contain complex syntax or variable expansion.

If neither of these approaches work, you may need to modify the pasted command to ensure that the commands are executed in the correct order. For example, you could break up the command sequence into multiple lines, or use a shell script to execute the commands in the desired order.

0

I would hazard a guess that there is something in you shell's readline, your PS1 prompt, or the PROMPT_COMMAND that discards pending characters from stdin.

Try typing these two lines without waiting for the first to complete:

sleep 10
id

If the id does not execute then you need to investigate the environment more closely.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .