25

I paste filenames/etc into Terminal all the time, and occasionally the contents of the clipboard isn't what I expect.

Often the result is several hundred lines of text (eg, source code) pasted into the command prompt, triggering god only knows what nastiness.

Is there some way to prevent bash from blindly executing whatever I paste in? I wish it would just paste the text, and let me decide after if I wanna execute it.

3
  • It's not often I'll accidentally paste the wrong thing into Terminal… but by golly it's frightening when it happens and multiple lines have executed before your fingers have even lifted from the Command-V keys. SilverWolf's answer (to switch from bash to zsh) is the simplest solution I've seen anywhere.
    – Kal
    Jun 18, 2020 at 3:54
  • @Kal if you're switching shells - try fish "Finally, a command line shell for the 90's". Properly handing multi-line paste is just one of many "90's" features in fish... it lets you paste multiple lines, but makes you hit return before it will execute the batch of commands. Or you can ctrl-c. Jul 9, 2020 at 3:43

8 Answers 8

10

Assuming you are using bash: If you activate emacs shortcuts with set -o emacs you can also use Emacs to edit the command line:

  • Type Ctrl-XCtrl-E at the prompt to start Emacs
  • Paste and edit your clipboard content into the Emacs buffer
  • Use Ctrl-XCtrl-C to exit Emacs and automatically run the command(s).
0
11

Use bracketed paste.

Bracketed paste is a feature where the terminal tells the shell that you pasted something instead of just typing it, so the shell can not run the command until you press Enter.

Terminal.app supports this, but not all terminals do.

Likewise, not all shells support it either. The version of bash that comes with OS X does not support bracketed paste (as of the time of writing, it's v3.2.57).

However, zsh does support bracketed paste:

zsh-bracketed-paste

Zsh is mostly compatible with bash (even scripts will probably work, unless you use some sort of really obscure feature), and better in many ways—for example, it even has multi-line command editing!

zsh-multiline-command

4
  • How do you activate bracketed paste? Jan 25, 2018 at 5:56
  • 2
    It's on by default if you use zsh. Try pasting in some one-liner! It should be reverse-highlighted like in my first screenshot, and if you hit Delete once it should delete the whole thing.
    – SilverWolf
    Jan 25, 2018 at 13:21
  • 1
    I actually found it by accident, then wondered why it wasn't in bash. Turns out the default bash is really old. (:
    – SilverWolf
    Jan 25, 2018 at 13:23
  • 1
    This is brilliant! Now I'm asking, why have I persisted with bash for so long?
    – Kal
    Jun 18, 2020 at 3:55
4

The simplest solution is probably to use a text editor as a buffer where you can double-check the contents, then copy from the text editor to Terminal. If you use TextEdit for this, you'll probably want to make sure it's in plain text mode (Format menu → Make Plain Text; ⇧⌘T) to avoid issues like links pasting as links, not URLs.

The other thing to note is that Bash will attempt to execute everything preceding a newline character, so if you're copying a block of text, you may want to ensure that your selection stops after the last character, rather than including the end of the line.

You want this: selection without newline

Not this: selection with newline

Of course, if you're copying stuff with newlines within the text (i.e. multiple paragraphs), then you'll need to manually edit the selection.

2
  • 2
    the problem is, I paste things into terminal several hundred times every day. using a text editor in the middle would be a pain in the ass Nov 22, 2012 at 3:43
  • An attacker can embed carriage returns in the text without them being visible on the screen, so your example of how to select text doesn't necessarily offer any protection.
    – sh1
    Nov 21, 2017 at 6:01
3

If you are using a recent version of Bash (v4.4; may have to install through homebrew):

  1. Add set enable-bracketed-paste on to your ~/.inputrc (source)
  2. Enable "Paste newlines as carriage returns" in your terminal profile picture_of_terminal_profile_tab
1

I get this too!

My solution is to paste using Launchbar's clipboard manager, with the hotkey Cmd+\. This brings up a list of recent clippings, allowing me to preview the result before pasting: if I don't see the content I expect, I hit escape before releasing Cmd. I can also use an arrow key to 'enter' a text clipping, allowing me to see the content line by line.

I believe most launchers do this - Alfred (powerpack addon) & Quicksilver (free), for example.

1

You might want to look into a clipboard manager. I use a free, light weight one called Jumpcut. It allows me to keep multiple clipboards and see what's stored in them before actually pasting the contents, all from the keyboard.

There are many clipboard managers out there, so if Jumpcut doesn't float your boat, maybe another will better fit your needs

1

Under Preferences -> Profiles -> Basic -> Advanced, check "Paste newlines as carriage returns". (Basic is the name of one profile. If you use another profile, you should choose that one instead.)

In some shells (zsh and bash work for me, tcsh does not) this will let you edit or abort (via Ctrl-C) what is pasted before any part of it is passed to the shell.

You may need to make a new Terminal window for the preference to start working.

I use this feature all the time, not only for pasting and editing complex commands, but also to view columnated text and sometimes to select and copy sub-rectangles by dragging with the option key.

2
  • I just learned that TextEdit also does the rectangular selection. Jan 15, 2020 at 15:29
  • This doesn't work for me in bash. Multiple lines are executed the moment they’re pasted, regardless of whether the 'Paste newlines as carriage returns' option is checked or not.
    – Kal
    Jun 18, 2020 at 3:44
0

You could put this little Bash script somewhere in your PATH:

#!/bin/bash

read -p "Are you sure you wish to execute \`$(pbpaste)\`? (Y/n) "    
[[ $REPLY =~ ^[Yy]?$  ]] && pbpaste | bash

If I put these contents in /usr/local/pbexecute for example and make it executable, I could safely execute pbexecute from the command-line, which would prompt my confirmation before executing the contents of the clipboard.

An alternative approach is to launch a text editor with the contents of the clipboard from within the shell and automatically execute the edited contents upon exiting. For example:

#!/bin/bash

PBTEMP=$(mktemp -t pbtemp)
pbpaste > $PBTEMP
nano -t $PBTEMP
source $PBTEMP
rm $PBTEMP
0

You must log in to answer this question.

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