Hacker News new | past | comments | ask | show | jobs | submit login
ZSH, tmux, Emacs and SSH: A copy-paste story (d46.us)
116 points by pmoriarty on May 6, 2018 | hide | past | favorite | 55 comments

This annoyance is one reason I avoid leaving Emacs. Eshell, tramp, dired, proced, docker-mode, etc... replace most of my terminal needs (including SSH). The same movement, search, and copy/paste bindings work everywhere, including in buffers pointing to remote machines.

Relevant: https://www.reddit.com/r/emacs/comments/6y3q4k/yes_eshell_is...

Exactly, this annoys me to no end, and for the same reason I'm pushing most of my computing into Emacs.

Emacs has a consistent UI and most packages have great composability. It's very easy to customize say notmuch email, org mode and pdf-tools to play together thanks to everything being an elisp function in a cohesive platform.

The same cannot be said about Unix CLI. While I love small utilities like parallel or ag, ncurses applications like mutt are little silos. They can be forced to talk to each other, but the result tends to be a bit inflexible and fragile.

This will limit your ability to present yourself to non-emacs users as someone fluent and proficient in a command line environment. (Spoken as a dedicated emacs user.)

I don't see how.

In my experience, the sort of person who's an emacs power user has clearly demonstrated they are capable of credentializing in tools.

At which point why would you assume they are any less capable than someone whose editor preference you know nothing about?

The people to whom I'm replying are using emacs not just as their text editor, but as their shell and as a wrapper around their ssh client. So they are likely to be perceived as less proficient at conventional shell usage.

Why does it matter that you present yourself as proficient?

When I said "present" I was referring to how you're likely to be perceived by colleagues. I was imagining someone working as a programmer, in a development team that makes heavy use of command line environments. (I'm a programmer and a dedicated emacs user in such a development team.)

It would also impede your ability to discuss and troubleshoot problems with command line environments with colleagues, since your colleagues would be using bash (or perhaps zsh) and conventional ssh, whereas you would be using a shell inside emacs and tramp.

Aside from EShell, the shells you use in Emacs (via M-x ansi-term or M-x shell) are whatever you want them to be. I use bash, but I know plenty who use ZSH and Fish.

I also do what OP does: I do as much as I can in Emacs to leverage what Emacs does best.

I think you underestimate how much respect your colleagues have for you, Myrmornis. The fact that you are using Emacs/Vim proficiently in most shops nowadays is a badge of respect to a lot of people already. Furthermore, most of Emacs's tooling won't hide you from the harsh realities of knowing how things work.

I use zsh and shell mode in Emacs. Knowing how to use a standalone shell, I've found, is synergistic with heavy Emacs use.

For one, and the most annoying, if a package update goes wrong, you're 'glove' is back to factory-made and you need to debug it to get it back. Shell helps here.

There are things that are easier to do in shell too. Batch processing of files over a whole directory tree is far more comfortable to me - especially binary format files.

I have shell scripts too. Automating parts of project development with Emacs is a bad idea since they can't be shared with colleagues who may be using, say, a JetBrains IDE.

Indeed. Apropos batch processing, I wrote about executing shell commands against marked files in Dired. It may tickle your fancy and help you out---assuming you're not familiar with it already of course!


Oh I didn't realise you were the author of mastering Emacs! I've learned a lot from your writings over the years. Thank you for that :)

Yes, the `find ... | xargs` pattern is exactly what I meant. This is awesome, thank you :)

I believe the poster you are responding to is likely thinking of an interview situation. At least, that is how I interpreted the comment.

I have been a happy Emacs user for nearly two years now, but I still don't use eshell. Is it only me, or is it really painfully slow?

Dan Luu wrote about terminal latency a while back [1]. Eshell is actually the shell with the least overall latency. Is is, though, very slow at sinking stdout, which is probably what you are noticing.

[1] https://danluu.com/term-latency/

Thanks for that link, but it does note that this is also latency, i.e. transmission delay, and at 500KB/s Eshell has a very high latency for bulk transfer especially considering it's 10MB/s slower than the nearest comptitor. How much this affects your work varies, but you will adapt and change you behaviour because of that latency.

Thanks for the read.

Eshell was only really useful for moving text between Emacs and external processes and in order to have a reasonably sensible shell on things like Windows 2000 boxes (it was never meant as a replacement for a system shell, but honestly, anything was good a replacement for cmd.exe). From the manual:

> Eshell is not a replacement for system shells such as bash or zsh. Use Eshell when you want to move text between Emacs and external processes; if you only want to pipe output from one external process to another (and then another, and so on), use a system shell, because Emacs's IO system is buffer oriented, not stream oriented, and is very inefficient at such tasks. If you want to write shell scripts in Eshell, don't; either write an elisp library or use a system shell.

So... there's a pretty tiny subset of people who need eshell, I guess. Most of the eshell users I know are either folks who got used to it from weird environments, or folks who just use emacs for everything so using it for their shell stuff, too, sort of makes sense.

Try the command in https://www.reddit.com/r/emacs/comments/74hetz/emacs_everywh... in your regular terminal vs eshell – piping is really slow in eshell. I guess it somehow reimplements `|` in elisp, possibly losing parallelism along the way. When I reran that command now in eshell, it took 13.4 seconds, during which time Emacs had 100% cpu all the time, and sort/uniq had almost nothing.

    > The problem is that pbpaste and pbcopy do not work under tmux
They do in recent macOS/tmux versions. You don't need reattach-to-user-namespace anymore.

These are my keybindings for copy/paste to clipboard:

    bind-key -T copy-mode-vi 'v' send -X begin-selection
    bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel pbcopy
    bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel pbcopy
    bind-key -T copy-mode-vi MouseDragEnd3Pane send -X copy-pipe-and-cancel pbcopy
`prefix + ]` then pastes using the clipboard contents

    Pasting into a terminal is interpreted literally, meaning an attacker can hide ;sudo do $really_evil_thing; in innocent looking, pasteable HTML with CSS trickery
TBH the fact that you can't tell what the fuck you are selecting in a web browser, is more of a UX bug of web browser than a problem with user behaviour or with applications receiving stuff from browsers.

That we are addressing this bug in terms of user education and workarounds in terminal emulators mostly says that we, as a community, have given up on web browsers ever making sense.

Author here, this is a rather pleasant Sunday surprise.

I'm not sure I'd recommend the route in the post. The setup is fragile with a sizable set of moving parts. Simpler options are doubling down on Emacs with TRAMP or using the client terminal emulator (e.g. iTerm) to copy and paste screen contents.

All these workarounds sound like a reason to use start using tramp more (apropos, https://www.youtube.com/watch?v=dljNabciEGg / http://www.howardism.org/Technical/Emacs/literate-devops.htm... is a pretty neat demo of combining org-babel and tramp).


There is also emamux, which seems to be able to copy from tmux: https://github.com/syohex/emacs-emamux/#emamuxyank-from-list...

As a vim user, tramp is one of two things that make me keep considering switching, the second being org mode.

I have found the transition to be pretty worthwhile. Evil is actually very good. There are also a few Evil-X packages that give sensible rebindings for other popular modes, like evil-magit.

It helped for me that I actually like lisps as well.

  local fake_clipboard=/tmp/clipboard-data.txt
  if is-ssh && is-port-in-use $clipper_port; then
    # Pipe to the clipper instance and the fake clipboard.
    tee >(nc localhost $clipper_port) "$fake_clipboard"
This is not a secure use of /tmp; and in general /tmp is not suitable for such inter-process communication.

Please create the fake clipboard file somewhere in the user's home directory.

> Please create the fake clipboard file somewhere in the user's home directory.

/tmp works perfectly fine for this purpose:

    local fake_clipboard=$(mktemp)
See mktemp(1), mkstemp(3), and mkdtemp(3). Please stop spreading these rumors that mislead people into writing programs that leave trash in my home directory.

The real issue with that code is the fact that Clipper is configured to listen on a TCP port instead of a socket file (placed in a /tmp subdirectory created by mktemp -d, of course).

> local fake_clipboard=$(mktemp)

So every time you copy or paste a new clipboard will be created. That defeats the purpose of clipboard.

That is what environment variables are for.

> in general /tmp is not suitable for such inter-process communication.

Yeah, it is not like X11 uses it for precisely that purpose or anything. ^_^

Why is /tmp not suitable for IPC? Is it because it's generally more open than a home directory?

First of all because anybody can read the contents of files there - presuming you don't have a sane umask.

Secondly because other uesrs might create files. Imagine somebody ran:

     ln -s /home/foo/.bash_profile /tmp/clipboard-data.txt
The next time you ran your clipboard-script your .bash_profile file would get its contents erased, due to the symlink.

Predictable filenames are a big security hole for multiuser systems, even though in practice you're probably the sole user of your desktop/laptop. I've reported numerous bugs of this kind, including this small set against GNU emacs:


Someone could put a symlink at that location to direct the output to clobber or create a file under your control.

Probably because everyone can access your clipboard

It's not a perfect solution, but I usually use the X11 primary selection trick: highlight some text with my mouse, and use the middle button to paste it. Any X11 window that supports text selection should work with it, including terminal emulators.

The downside, of course, is that X11 selections aren't real clipboards: they disappear as soon as their origin window is destroyed. That means you have to keep the source window open while you do your pasting, which may clash with your workflow.

"The downside, of course, is that X11 selections aren't real clipboards: they disappear as soon as their origin window is destroyed."

Check out parcellite.[1] It gives a persistent clipboard history under X.

[1] - http://parcellite.sourceforge.net/

The downside I found to parcellite is that it doesn't handle images at all. Instead I've been stuck using xfce4-clipman, even though I've actually wanted to switch to parcellite so I can have a less DE specific solution.

If you're looking for an Emacs terminal+x-clipboard solution, I created an elisp pull request [1] for Spacemacs for adding that kind of support and handling SSH, Tmux, and Emacs. Note, this isn't a perfect solution, but it works well for linux to linux ssh and tmux. Feel free to contribute.

[1] https://github.com/syl20bnr/spacemacs/pull/8864

One of the reason I use a linux/x11 environment for work is the middle button paste buffer. (I have no idea what it's real name is for)

any text selected is automatically copied into the buffer (which is seperate from ctrl-c/v)

It doesn't overcome the "bugger I've pasted rm -rf /*" problem, but its wonderfully useful

It's a Selection and its name is PRIMARY. Nothing is copied, that's the trick for the clipboard on every vaguely modern OS too. (In X11 the clipboard is a Selection named CLIPBOARD). Instead applications tell the system "I have the clipboard" (or in X, "I have this named selection") and when a paste operation happens the exact bits to be moved are figured out only then.

In bash I use ctrl-X-E and paste into the default editor using the emulator's paste function (ctrl-shift-v in my current emulator). This works in bash ssh sessions too.

> a terminal will default to interpreting what you pasted the same as entering a sequence of commands

Another reason why urxvt[1] is the best terminal emulator: the "confirm-paste"[2] extension. Any time the terminal receives a paste matching /[\n\r]/, the terminal shows you the incoming text in an overlay and asks for confirmation.

Enable it with the option "-pe confirm-paste" or add something like this to ~/.Xresources

    URxvt*perl-ext-common: default,confirm-paste
(or added to your list of extensions, if you are not using the "default" set)

(afterwords, don't forget to run "xrdb -merge ~/.Xresources")

[1] http://software.schmorp.de/pkg/rxvt-unicode.html

[2] http://cvs.schmorp.de/rxvt-unicode/src/perl/confirm-paste?vi...

The confirm-paste plugin won't necessarily save you from malicious pastes.

See my comments in https://lwn.net/Articles/749992/ .

Thanks, I will have to fix that, probably by trapping any non-printing, non-whitespace code, not just [\n\r]. I can't think of any situation I would not want to confirm past of text containing control codes, so it should be an easy fix.

Incidentally, while I wasn't vulnerable to C-o because I have a lot of remapped bindings. However, I am vulnerable to the two other codes that I bound to operate-and-get-next.

> Enumerating badness usually doesn't end well.

I wish more people that create and/or operate networked devices understood that.

Clipboard control in terminals... yet.... not a single mention of OSC 52.


Then they are using /tmp to facilitate IPC... What a horrible thing.

Author here, OSC 52 looks promising. I didn't realize there was an escape code for clipboard integration.

You're the second person to mention /tmp for IPC is bad. Why is it bad?

[1]: https://medium.freecodecamp.org/tmux-in-practice-integration...

The reason is security. It isn't much of a problem on a laptop only you use (since then your home directory is likely none safer), but on a shared machine, or at least a shared file system, other accounts can access stuff in /tmp just fine, e.g. by replacing the file with a symlink. To perform a delete operation on a file, you only need execute permissions on the containing directory (iirc), but nothing on the file itself.

Last time I checked, very few terminals implemented OSC 52.

Most "terminals" just use libvte, which, true, doesn't support most control commands, including OSC 52[1].

However, xterm supports it, alacritty supports it, hterm and many others...

A stock Chromebook[2] supports OSC 52, and practically every Linux distro has options. For OSX, I know iTerm supports it if you enable the clipboard integration toggle under preferences.

A bigger issue here, though, is a recent discussion about removing support for control sequences, in general[3] for many terminals that use libvte. Some view them as a vulnerability, but others view them as a feature.[4]

[1] https://bugzilla.gnome.org/show_bug.cgi?id=795774

[2] https://chromium.googlesource.com/apps/libapps/+/master/nass...

[3] http://seclists.org/oss-sec/2017/q2/197

[4] http://seclists.org/oss-sec/2018/q2/31

I just went through this hell when setting up my new Macbook Pro at my new job. Setting up iterm, tmux, zsh to properly cut and paste was so frustrating. By default I should be able to yank into my clipboard and paste into vim from my clipboard in tmux. I can't figure out why this isn't the default behavior.

to add my an 50 cent... i hacked together a tool that does not rely on xclip or pbcopy https://github.com/grafoo/netsel you'd start it on your x11 machine and remote forward the tcp port to the remote hosts.

Regarding pasting to a terminal with zsh, I've been using a recipe from here http://www.zsh.org/mla/users/2011/msg00367.html and it's been great.

> Pasting into a terminal is interpreted literally, meaning an attacker can hide ;sudo do $really_evil_thing; in innocent looking, pasteable HTML with CSS trickery. Therefore, we can’t blindly paste text into a terminal.

It depends on the probability that an "attacker" has done such a thing, which depends on the website among other things.

Sincere question: is it really appropriate that so many of us think in such black and white terms about security? I submit that it is not appropriate to strive for zero-probability-of-being-pwned solutions in all personal computing scenarios; there is a cost benefit analysis always.

Author here. I figured it was an easy enough hole to fix that it was worth including. The ZSH line editor will paste without sending the command so you don't really harm usability.

Installing dev tools via paste and pipe into sh is fairly common:

    curl https://sh.rustup.rs -sSf | sh
The overall risk is probably really low, but there's no downsides.

Cool, I’m sure that’s good advice! I’ve just always been curious about the general question — there’s a large contingent of programmers who role their eyes whenever they see curl|sh and there’s probably an equally large component who think that life’s short and contains more important issues than command line security neuroticism...

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact