15

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.

9

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).
  • I assume you mean Ctrl instead of Cmd. Also, without doing set -o emacs it seems to use $EDITOR. Thanks! this is perfect. – Abhi Beckert Nov 22 '12 at 3:52
5

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.

  • 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 – Abhi Beckert Nov 22 '12 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 '17 at 6:01
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

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

  • How do you activate bracketed paste? – Abhi Beckert Jan 25 '18 at 5:56
  • 1
    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 '18 at 13:21
  • 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 '18 at 13:23
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
  • Why the escaped back ticks? Using '' should work as well. – nohillside Nov 21 '12 at 6:53
  • @patrix If I don't escape the backticks, bash will already execute it while prompting. – Gerry Nov 21 '12 at 6:54
  • Shouldn't omitting the backticks do the trick as well then? – nohillside Nov 21 '12 at 7:35
  • @patrix Oh, yes ofcourse, that's just a matter of preference on how you want to format the prompt. I chose backticks because they are the command substitution operator and are commonly used to visually markup commands (see StackExchange editing). – Gerry Nov 21 '12 at 7:53
  • I'm ok with this :-) It just seems kind of complicated – nohillside Nov 21 '12 at 8:31

You must log in to answer this question.

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