Emacs Tramp and Speedier SSH Access

# Tramp #

I often find myself editing files in terminals on remote machines, and I really need to add [Tramp] to my muscle memory. Tramp is an Emacs package (installed by default?) for editing remote files via ssh. It allows you to open files with urls like this: `/ssh:user@host#port:/path/to/file`.

Note: I use `ssh` instead of `scp` (used in all of the examples) because the webpage says it’s faster and also because it supports the `#port` piece while `scp` does not. Also, the `user@` and `#port` pieces are optional. So feel free to use the minimum: `/ssh:host:/path/to/file`.

[Tramp]: http://www.emacswiki.org/emacs/TrampMode


## sudo, too ##

Even better, have you ever opened a root-owned file in an editor, made some changes, only to have the editor tell you that the file is read-only because you didn’t use sudo? For example, if you opened `/etc/root_owned_file` using Emacs, write the buffer to a “new” file, ^X^W, using this tramp-enabled file path: `/sudo::/etc/root_owned_file`. Emacs doesn’t know that you’re writing to the same file. It will open the file using tramp and sudo, save your changes, and replace your non-sudo buffer with the new one.

# OpenSSH ControlMaster #

The biggest problem I’ve had using Tramp mode, though, is latency. If your connection isn’t local, and you have the **good** habit of constantly saving, the delays can be annoying or at least jarring. On the EmacsWiki Tramp page, [there’s a hint][ControlMaster] about using the ControlMaster option in OpenSSH. With ControlMaster set, you simply open a regular ssh session to your remote host, and OpenSSH will use that already established connection for all of your future file access.

[ControlMaster]: http://archive09.linux.com/feature/54498

## Enabling it ##

Just put the following in `~/.ssh/config`:

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

That’s it! Your welcome. Enjoy your better life. Here’s the effect in action on a local machine:

$ ./time_ssh_access.py
0.36 0.34 0.33 0.36 0.31 0.27 0.33 0.34 0.35 0.35
Average: 0.334
# ControlMaster added to ~/.ssh/config and a new terminal opened
$ ./time_ssh_access.py
0.02 0.02 0.04 0.02 0.02 0.04 0.01 0.02 0.02 0.02
Average: 0.023

That’s a 93% improvement. On a remote machine, times went from 0.861 down to 0.161 for an 81% improvement.

### time_ssh_access.py ###

Here’s the script used for testing. It uses the [_sh_][sh_module] python module which is so awesome it deserves its own blog post.

#!/usr/bin/env python -u

from sh import time

host = 'machine.local'
response = 'machine'

total = 0.0
for x in xrange(10):
    output = time('ssh', host, 'hostname')
    if output.exit_code != 0 or output.stdout.strip() != response:
        print('Failed')
        break

    times = output.stderr.split()
    # You may need to adjust this line depending on your version of the _time_ command.
    index = times.index('real') - 1
    print times[index],
    total += float(times[index])

print
print 'Average: {}'.format(total/10.0)

[sh_module]: https://github.com/amoffat/sh

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *