Some bits of how Bash and GNU Readline's "bracketed paste" mode behaves

August 6, 2021

Recent versions of Bash and GNU Readline now default to special handling of pasting into them, in what is called "bracketed paste" mode. This mode requires you to explicitly hit Return in order to have the pasted text accepted, and allows you to edit the paste before then. This simple description might leave you wondering how bracketed paste mode interacts with various other things, and as it happens I have done some experiments here (out of curiosity, since bracketed paste mode is not for us).

First, although it's not completely clear from the description, bracketed paste treats multiple lines pasted at once as a single unit for the purposes of editing and accepting them (or rejecting them with a Control-C). After they've been accepted, Bash (and presumably Readline) will treat them as separate lines for history and so on. This is probably the behavior you want if you're pasting multiple commands.

Second, bracketed paste sends all of your pasted text to Bash (or the Readline based program you're using), regardless of how it would otherwise be interpreted if you typed it, and Bash will process all lines as command lines. That sounds abstract, so let's give you a concrete example. Suppose that you have the following text to cut and paste from some instructions:

cat >/etc/some-config.conf
directive one
directive two

If you paste this normally (and then hit Control-D afterward), the some-config.conf winds up with the two directives in it, because Bash first runs the cat and then the remaining two lines are read by cat. If you paste this into a bracketed paste Bash and then hit Return to accept it all, Bash first runs cat, with it reading from the terminal as standard input and waiting for you to type something to it, and then when you hit Ctrl-D it will attempt to run 'directive one' and 'directive two' as commands. There's no visual indication that this is happening and that Bash has grabbed the second and third lines for itself.

On the one hand, in the Unix model it's hard to see how Bash could do this differently without deep cooperation from the kernel terminal driver (which isn't available). On the other hand, this makes bracketed paste mode dangerously different from un-bracketed paste in a way that is not particularly obvious and I think is not necessarily intuitive.

PS: Because I tested it, Bash really takes all of your pasted text as command lines, even if one of the pasted commands is 'read', which Bash handles internally and so could pass your text to. I assume that internally, Readline is buffering all of this up as command input. Programs that use Readline for multiple things might mix your pasted input in a different way.


Comments on this page:

From 193.219.181.219 at 2021-08-07 10:13:05:

I would probably say that expecting the rest of the paste to be fed into stdin isn't a very good habit in the first place, and would prefer pasting this instead:

cat >/etc/some-config.conf <<'EOF'
directive one
directive two
EOF

Overall, a heredoc works better as it's compatible with bracketed paste, works equally in interactive and script contexts, does not require the final Ctrl+D, is clearer about whether you can press Ctrl+D already or whether the system is still just loading /bin/cat, etc.

I have solved the problem adding that condition to my .bashrc:

if [[ $- == *i* ]]; then
   bind 'set enable-bracketed-paste off'
fi

Maybe it can help you.

By Miksa at 2021-09-10 08:34:10:

My coworker raised the concern that bracketed paste would teach the user to press enter automatically just to be able to edit their paste, and this might cause problems when they come across something that doesn't use bracketed paste. It might be better if bracketed paste required some other key like Space or Tab.

But otherwise this could be a nice feature. We had one important service get wiped, when the admin admin accidentally right-clicked a PuTTY window with rooted session and pasted a bunch of script containing something like 'rm -rf ${MISSING_VAR}/'.

Or as an alternative I would at least want a widget that showed in real time what my paste buffer contains.

Written on 06 August 2021.
« Using journalctl's ability to show only one service
Some thoughts on new top-level domains being used for spam »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Aug 6 22:28:25 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.