在 SSH 中用本地的 Emacs 打开文件

2017-06-01

打开终端,通过 SSH 登录到服务器后,常需要编辑配置文件,此时再切换到 Emacs 窗口用 C-x C-f (find-file) 打开,可能不是很方便。我们可以建立一个反向的 SSH 隧道,让服务器也能控制本地的机器。

一个实际 workflow:

# 登录远程服务器
xcy@macbook ~$ ssh vps
# 定义一个 Shell 函数 (ff 是 find-file 的缩写)
root@vps ~# ff () { ssh -p 9999 xcy@localhost "emacsclient --no-wait /ssh:vps:$(readlink -f $1)"; }
# 通知本地 Emacs 打开服务器上的文件
root@vps ~# ff /etc/apache2/apache2.conf

1 设置转发

在本地的 ~/.ssh/config 中加入 RemoteForward 9999 localhost:22, 其中 9999 代表服务器上的一个空闲端口

Host vps
     HostName xuchunyang.me
     User root
     ControlMaster auto
     ControlPath ~/.ssh/control:%h:%p:%r
     RemoteForward 9999 localhost:22

然后登录服务器之后,透过 ssh -p 9999 localhost 就能控制本地了:

xcy@macbook ~$ pwd
/Users/xc
xcy@macbook ~$ ssh vps
root@vps ~# pwd
/root
root@vps ~# ssh -p 9999 xcy@localhost pwd
/Users/xcy

2 ssh user@hostname command 时的 $PATH 问题

通过 ssh user@hostname command 运行 Shell 命令时,SSH 以把 $SHELL 作为 non-interactive non-login shell 加载相应的初始化配置,对于 Bash 来说,执行的是 ~/.bashrc ,而不会执行 ~/.bash_profile 。你可以通过 $TERM 识别出 SSH 并加载相应的配置

if [ "$TERM" == "dumb" ]; then
    . ~/.bash_profile
    return
fi

由于这里只涉及到 emacsclient ,也完全可以使用完整的路径,而不必担心 $PATH 的问题。这里需要指出是因为 macOS 自带了 Emacs 22,它所提供的 emacsclient 不能和现代的 Emacs Server 配合使用,而且容易造成误解。

3 参考链接

Tags:

加载 Disqus 评论