Analysis
A possible cause may be the use_pty
flag. See man 5 sudoers
[emphasis mine]:
use_pty
If set, and
sudo
is running in a terminal, the command will be run in a new pseudo-terminal. If thesudo
process is not attached to a terminal,use_pty
has no effect.A malicious program run under
sudo
may be capable of injecting commands into the user's terminal or running a background process that retains access to the user's terminal device even after the main program has finished executing. By running the command in a separate pseudo-terminal, this attack is no longer possible. This flag is on by default forsudo
1.9.14 and above.
With use_pty
sudo
acts as a relay and it will read its stdin as soon as possible, even if the inner command is not going to read its stdin. The situation is similar to what ssh
does.
The default behavior changed in the past; this explains why things stopped working for you.
Solution
You can restore the old behavior. Start an elevated shell with sudo -i
, let this be a "just in case" shell. Elsewhere run sudo visudo
and turn the flag off:
Defaults !use_pty
Save the file, exit the editor. Check if sudo
still works for your regular user. If it doesn't work then use the elevated shell to fix the sudoers
file. Exit the elevated shell only after you confirm that sudo
works for your regular user.
Note
With !use_pty
, the command run with sudo
may read directly from the terminal and consume what you pasted. A command run without sudo
also may. Your example commands do not do this, but in general a command may. And if your sudo
was going to ask for password, it would also consume some part of what you pasted.
This is something the bracketed paste can solve. To avoid mishaps, enable bracketed paste in your Bash:
bind 'set enable-bracketed-paste on'
and make sure your terminal emulator uses the functionality when pasting. If bracketed paste works, a pasted multi-line snippet (like the one in question) will not be executed on the fly (allowing earlier command(s) to consume further input). It will be buffered by the shell and executed after you hit Enter.
With bracketed paste your snippet will work, no matter if use_pty
is set or unset. For the reason explained in the cited manual it's good to set the flag.
Bracketed paste enabled and working, and use_pty
set in sudoers
is the safest, most robust setup when you want to paste multi-line snippets containing sudo
. It will work properly even if sudo
is going to ask for your password.
The concern from your comment "I don't see what output goes with what command" can be solved with set -v
and/or set -x
. See help set
for details.