The official name is “Tramp”. This is used in comments, docstrings, and everywhere speaking about TRAMP.
However, for historical reasons this is formatted as “@sc{Tramp}” in the TRAMP manual. So it looks different there.
TRAMP is available at the GNU URL:
https://ftp.gnu.org/gnu/tramp/
TRAMP’s GNU project page is located here:
The package works successfully on Emacs 26, Emacs 27, Emacs 28, and Emacs 29.
While Unix and Unix-like systems are the primary remote targets, TRAMP has equal success connecting to other platforms, such as MS Windows 7/8/10.
TRAMP does many things in the background, some of which depends on network speeds, response speeds of remote hosts, and authentication delays. During these operations, TRAMP’s responsiveness slows down. Some suggestions within the scope of TRAMP’s settings include:
tramp-persistency-file-name
, which is where
TRAMP caches remote information about hosts and files. Caching
is enabled by default. Don’t disable it.
Set remote-file-name-inhibit-cache
to nil
if remote
files are not independently updated outside TRAMP’s control.
That cache cleanup will be necessary if the remote directories or
files are updated independent of TRAMP.
(setq vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)" vc-ignore-dir-regexp tramp-file-name-regexp))
If this is too radical, because you want to use version control
remotely, trim vc-handled-backends
to just those you care
about, for example:
(setq vc-handled-backends '(SVN Git))
remote-file-name-inhibit-locks
to
t
if you know that different Emacs sessions are not modifying
the same remote file.
tramp-verbose
to 3 or lower,
default being 3. Increase trace levels temporarily when hunting for
bugs.
Three main reasons for why TRAMP does not connect to the remote host:
TRAMP needs a clean recognizable prompt on the remote host for accurate parsing. Shell prompts that contain escape sequences for coloring cause parsing problems. Remote shell setup hints for customizing prompt detection using regular expressions.
To check if the remote host’s prompt is being recognized, use this test: switch to TRAMP connection buffer *tramp/foo*, put the cursor at the top of the buffer, and then apply the following expression:
M-: (re-search-forward (concat tramp-shell-prompt-pattern "$")) RET
If the cursor has not moved to the prompt at the bottom of the buffer, then TRAMP has failed to recognize the prompt.
When using zsh on remote hosts, disable zsh line editor because zsh uses left-hand side and right-hand side prompts in parallel. Add the following line to ~/.zshrc:
[[ $TERM == "dumb" ]] && unsetopt zle && PS1='$ ' && return
This uses the default value of tramp-terminal-type
, "dumb"
,
as value of the TERM
environment variable. If you want to use
another value for TERM
, change tramp-terminal-type
and
this line accordingly.
Alternatively, you could set the remote login shell explicitly. See Remote shell setup hints for discussion of this technique,
When using fish shell on remote hosts, disable fancy formatting by adding the following to ~/.config/fish/config.fish:
function fish_prompt if test $TERM = "dumb" echo "\$ " else … end end
When using WinSSHD on remote hosts, TRAMP does not recognize the strange prompt settings.
A similar problem exist with the iTerm2 shell integration, which sends proprietary escape codes when starting a shell. This can be suppressed by changing the respective integration snippet in your ~/.profile like this:
[ $TERM = "dumb" ] || \ test -e "${HOME}/.iterm2_shell_integration.bash" && \ source "${HOME}/.iterm2_shell_integration.bash"
And finally, bash’s readline should not use key bindings like ‘C-j’ to commands. Disable this in your ~/.inputrc:
$if term=dumb
# Don't bind Control-J or it messes up TRAMP.
$else
"\C-j": next-history
$endif
TRAMP suppresses echos from remote hosts with the
stty -echo
command. But sometimes it is too late to suppress
welcome messages from the remote host containing harmful control
characters. Using sshx or scpx methods can avoid
this problem because they allocate a pseudo tty. See Inline methods.
Set tramp-chunksize
to 500 to get around this problem, which is
related to faulty implementation of process-send-string
on
HP-UX, FreeBSD and Tru64 Unix systems. Consult the documentation for
tramp-chunksize
to see when this is necessary.
Set file-precious-flag
to t
for files accessed by
TRAMP so the file contents are checked using checksum by
first saving to a temporary file.
(add-hook 'find-file-hook (lambda () (when (file-remote-p default-directory) (set (make-local-variable 'file-precious-flag) t))))
When connecting to a local host, TRAMP uses some internal
optimizations. They fail when Emacs runs in a chrooted environment.
In order to disable those optimizations, set user option
tramp-local-host-regexp
to nil
.
Yes. OpenSSH
has added support for FIDO hardware
devices via special key types *-sk. TRAMP supports
the additional handshaking messages for them. This requires at least
OpenSSH
8.2, and a FIDO U2F compatible
security key, like yubikey, solokey, nitrokey, or titankey.
Recent versions of smbclient
do not support old connection
protocols by default. In order to connect to such a host, add a
respective option:
(add-to-list 'tramp-smb-options "client min protocol=NT1")
Note that using a deprecated connection protocol raises security problems, you should do it only if absolutely necessary.
ANSI escape sequences from the remote shell may cause errors in TRAMP’s parsing of remote buffers.
To test if this is the case, open a remote shell and check if the output
of ls
is in color.
To disable ANSI escape sequences from the remote hosts, disable ‘--color=yes’ or ‘--color=auto’ in the remote host’s .bashrc or .profile. Turn this alias on and off to see if file name completion works.
This may be related to globbing, which is the use of shell’s ability to expand wild card specifications, such as ‘*.c’. For directories with large number of files, globbing might exceed the shell’s limit on length of command lines and hang. TRAMP uses globbing.
To test if globbing hangs, open a shell on the remote host and then
run ls -d * ..?* > /dev/null
.
When testing, ensure the remote shell is the same shell
(/bin/sh
, ksh
or bash
), that
TRAMP uses when connecting to that host.
Make Emacs beep after reading from or writing to the remote host with the following code in ~/.emacs.
(add-hook 'tramp-handle-write-region-hook 'beep) (add-hook 'tramp-handle-file-local-copy-hook 'beep)
Install tramp-theme from GNU ELPA via Emacs’s Package Manager.
Enable it via M-x load-theme RET tramp RET. Further
customization is explained in user option
tramp-theme-face-remapping-alist
.
Emacs computes the dired
options based on the local host but
if the remote host cannot understand the same ls
command,
then set them with a hook as follows:
(add-hook 'dired-before-readin-hook (lambda () (when (file-remote-p default-directory) (setq dired-actual-switches "-al"))))
Due to the remote shell saving tilde expansions triggered by
TRAMP, the history file is probably growing rapidly.
TRAMP can suppress this behavior with the user option
tramp-histfile-override
. When set to t
, environment
variable HISTFILE
is unset, and environment variables
HISTFILESIZE
and HISTSIZE
are set to 0. Don’t use this
with bash
5.0.0. There is a bug in bash
which
lets bash
die.
Alternatively, tramp-histfile-override
could be a string.
Environment variable HISTFILE
is set to this file name then. Be
careful when setting to /dev/null; this might result in
undesired results when using bash
as remote shell.
Another approach is to disable TRAMP’s handling of the
HISTFILE
at all by setting tramp-histfile-override
to
nil
. In this case, saving history could be turned off by
putting this shell code in .bashrc or .kshrc:
if [ -f $HOME/.sh_history ] ; then /bin/rm $HOME/.sh_history fi if [ "${HISTFILE-unset}" != "unset" ] ; then unset HISTFILE fi if [ "${HISTSIZE-unset}" != "unset" ] ; then unset HISTSIZE fi
For ssh-based method, add the following line to your ~/.ssh/environment:
HISTFILE=/dev/null
Emacs can trash file instead of deleting them. Remote files are always trashed to the local trash, except remote encrypted files (see Protect remote files by encryption), which are deleted anyway.
If Emacs is configured to use the XDG conventions for the trash directory, remote files cannot be restored with the respective tools, because those conventions don’t specify remote paths. Such files must be restored by moving them manually from ${XDG_DATA_HOME}/Trash/files/, if needed.
Temporary files are kept in your temporary-file-directory
directory, which is often /tmp/. By default, they have the
file name prefix "tramp."
. If you want to change this prefix, for
example because you want to identify temporary files produced by
file-local-copy
in your package, you can bind the variable
tramp-temp-name-prefix
temporarily:
(let ((tramp-temp-name-prefix "my-prefix.")) (file-local-copy "/ssh::.emacs")) ⇒ "/tmp/my-prefix.HDfgDZ"
Adapt several of these approaches to reduce typing. If the full name is /ssh:news@news.my.domain:/opt/news/etc, then:
If you always apply the default method (see Selecting a default method), you could use the simplified TRAMP syntax (see Alternative file name syntax):
(customize-set-variable 'tramp-default-method "ssh") (tramp-change-syntax 'simplified)
The reduced typing: C-x C-f
/news@news.my.domain:/opt/news/etc
RET.
You can define default methods and user names for hosts, (see Selecting a default method, see Selecting a default user):
(custom-set-variables '(tramp-default-method "ssh") '(tramp-default-user "news"))
The reduced typing: C-x C-f /-:news.my.domain:/opt/news/etc RET.
Note that there are some useful shortcuts already. Accessing your local host as ‘root’ user, is possible just by C-x C-f /su:: RET.
Programs used for access methods already offer powerful configurations (see Selecting config files for user/host name completion). For ssh, configure the file ~/.ssh/config:
Host xy HostName news.my.domain User news
The reduced typing: C-x C-f /ssh:xy:/opt/news/etc RET.
Depending on the number of files in the directories, host names completion can further reduce key strokes: C-x C-f /ssh:x TAB.
For long file names, set up environment variables that are expanded in the minibuffer. Environment variables are set either outside Emacs or inside Emacs with Lisp:
(setenv "xy" "/ssh:news@news.my.domain:/opt/news/etc/")
The reduced typing: C-x C-f $xy RET.
Note that file name cannot be edited here because the environment variables are not expanded during editing in the minibuffer.
Redefine another key sequence in Emacs for C-x C-f:
(global-set-key
[(control x) (control y)]
(lambda ()
(interactive)
(find-file
(read-file-name
"Find TRAMP file: "
"/ssh:news@news.my.domain:/opt/news/etc/"))))
Simply typing C-x C-y would prepare minibuffer editing of file name.
See the Emacs Wiki for a more comprehensive example.
Abbreviation list expansion can be used to reduce typing long file names:
(add-to-list 'directory-abbrev-alist '("^/xy" . "/ssh:news@news.my.domain:/opt/news/etc/"))
The reduced typing: C-x C-f /xy RET.
Note that file name cannot be edited here because the abbreviations are not expanded during editing in the minibuffer. Furthermore, the abbreviation is not expanded during TAB completion.
The abbrev-mode
gives additional flexibility for editing in the
minibuffer:
(define-abbrev-table 'my-tramp-abbrev-table '(("xy" "/ssh:news@news.my.domain:/opt/news/etc/")))
(add-hook 'minibuffer-setup-hook (lambda () (abbrev-mode 1) (setq local-abbrev-table my-tramp-abbrev-table)))
(advice-add 'minibuffer-complete :before 'expand-abbrev)
The reduced typing: C-x C-f xy TAB.
The minibuffer expands for further editing.
Use bookmarks to save TRAMP file names.
Upon visiting a location with TRAMP, save it as a bookmark with menu-bar edit bookmarks set.
To revisit that bookmark: menu-bar edit bookmarks jump.
recentf remembers visited places.
Keep remote file names in the recent list without have to check for their accessibility through remote access:
(recentf-mode 1)
Reaching recently opened files: menu-bar file Open Recent.
Since filecache remembers visited places, add the remote directory to the cache:
(with-eval-after-load 'filecache (file-cache-add-directory "/ssh:news@news.my.domain:/opt/news/etc/"))
Then use directory completion in the minibuffer with C-x C-f C-TAB.
bbdb has a built-in feature for Ange FTP files, which also works for TRAMP file names.
Load bbdb in Emacs:
(require 'bbdb) (bbdb-initialize)
Create a BBDB entry with M-x bbdb-create-ftp-site RET. Then specify a method and user name where needed. Examples:
M-x bbdb-create-ftp-site RET Ftp Site: news.my.domain RET Ftp Directory: /opt/news/etc/ RET Ftp Username: ssh:news RET Company: RET Additional Comments: RET
In BBDB buffer, access an entry by pressing the key F.
Thanks to TRAMP users for contributing to these recipes.
When saving ad-hoc multi-hop TRAMP file names (see Declaring multiple hops in the file name) via bookmarks, recent files, filecache, bbdb, or another package, use the full ad-hoc file name including all hops, like /ssh:bird@bastion|ssh:news.my.domain:/opt/news/etc.
Alternatively, when saving abbreviated multi-hop file names
/ssh:news@news.my.domain:/opt/news/etc, the user
option tramp-save-ad-hoc-proxies
must be set non-nil
value.
Configure Emacs Client
Then on the remote host, start the Emacs Server:
(require 'server) (setq server-host (system-name) server-use-tcp t) (server-start)
If (system-name)
of the remote host cannot be resolved on the
local host, use IP address instead.
Copy from the remote host the resulting file ~/.emacs.d/server/server to the local host, to the same location.
Then start Emacs Client from the command line:
$ emacsclient /ssh:user@host:/file/to/edit
user
and host
refer to the local host.
To make Emacs Client an editor for other programs, use a wrapper script emacsclient.sh:
#!/bin/sh emacsclient /ssh:$(whoami)@$(hostname --fqdn):$1
Then change the environment variable EDITOR
to point to the
wrapper script:
$ export EDITOR=/path/to/emacsclient.sh
The buffer-local variable default-directory
tells this. If the
form (file-remote-p default-directory)
returns non-nil
,
the buffer is remote. See the optional arguments of
file-remote-p
for determining details of the remote connection.
If the local machine Emacs is running on changes its network integration, remote hosts could become unreachable. This happens for example, if the local machine is moved between your office and your home without restarting Emacs.
In such cases, the command tramp-rename-files
can be used to
alter remote buffers’ method, host, and/or directory names. This
permits saving their contents in the same location via another network
path, or somewhere else entirely (including locally). see Renaming remote files.
recentf-list
?
When TRAMP cleans a connection, it removes the respective
remote file name(s) from recentf-list
. This is needed, because
an unresponsive remote host could trigger recentf
to connect
that host again and again.
If you find the cleanup disturbing, because the file names in
recentf-list
are precious to you, you could add the following
two forms in your ~/.emacs after loading the tramp
and
recentf
packages:
(remove-hook 'tramp-cleanup-connection-hook #'tramp-recentf-cleanup)
(remove-hook 'tramp-cleanup-all-connections-hook #'tramp-recentf-cleanup-all)
TRAMP comes with compatibility code for different Emacs versions. When you see such a message (the text might differ), you don’t use the Emacs built-in version of TRAMP, and you must recompile it. In case you have installed TRAMP from GNU ELPA, see https://www.gnu.org/software/tramp/#ELPA-Installation. Otherwise, see https://www.gnu.org/software/tramp/#Recompilation.
Timers, process filters and sentinels, and other event based functions can run at any time, when a remote file operation is still running. This can cause TRAMP to block. When such a situation is detected, this error is triggered. It should be fixed in the respective function (sending an error report will help), but for the time being you can suppress this error by the following code in your ~/.emacs:
(setq debug-ignored-errors (cons 'remote-file-error debug-ignored-errors))
TRAMP has changed the signature of an internal function. External packages implementing an own TRAMP backend must follow this change. Please report this problem to the author of that package.
For the running session, TRAMP disables the external package, and you can continue to work. If you don’t want to see this error while activating TRAMP, you can suppress it by the same code as above in your ~/.emacs:
(setq debug-ignored-errors (cons 'remote-file-error debug-ignored-errors))
There are packages that call TRAMP without the user ever entering a remote file name. Even without applying a remote file syntax, some packages enable TRAMP on their own. How can users disable such features.
Disable TRAMP file name completion:
(customize-set-variable 'ido-enable-tramp-completion nil)
Disable remote directory tracking mode:
(rlogin-directory-tracking-mode -1)
(customize-set-variable 'tramp-default-method "ftp")
If you want to enable Ange FTP’s syntax, add the following form:
(tramp-change-syntax 'simplified)
tramp-mode
to
nil
in .emacs. Note, that we don’t use
customize-set-variable
, in order to avoid loading TRAMP.
(setq tramp-mode nil)
tramp-ignored-file-name-regexp
to a proper regexp in
.emacs. Note, that we don’t use
customize-set-variable
, in order to avoid loading
TRAMP.
(setq tramp-ignored-file-name-regexp "\\`/ssh:example\\.com:")
This is needed, if you mount for example a virtual file system on your local host’s root directory as /ssh:example.com:.
The difference is that Ange FTP uses ftp
to transfer files
between the local and the remote host, whereas TRAMP uses a
combination of ssh
and scp
or other work-alike
programs.