暗无天日

=============>DarkSun的个人博客

如何让Tramp支持访问Termux

Tramp ssh协议访问Termux

当使用Tramp通过ssh访问Termux上的文件时,你可能会发现出现下面这样的错误:

tramp-file-name-handler: Method ‘ssh’ should specify both encoding and decoding command or an scp program

这是因为Termux是一个prefixed Linux环境,它的目录结构是构建在 /data/data/com.termux/files/usr 下的. 若你在Termux上查看它的 PATH 环境变量会发现它的 PATH 环境变量并不是我们常见的 /bin:/usr/bin 这种位于根目录下的路径

echo $PATH
/sbin:/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets

因此,当Tramp尝试在这些常见的 bin 目录中搜索Decode和Encode程序时就会找不到。

解决方法其实很简单,往 tramp-remote-path 变量中加入 tramp-own-remote-path 就行了.

(setq tramp-remote-path `(,@tramp-remote-path tramp-own-remote-path))

Tramp 根据 tramp-remote-path 中配置的路径来搜索远程主机上的程序,当它看到 tramp-own-remote-path 时会将其替换成远程主机上的 PATH 变量中定义的路径。

Tramp 与 org-babel 联用

即使经过上面的配置,当将Tramp与org-babel联用时,依然会有类似下面的错误出现:

tramp-file-name-handler: Couldn’t write region to ‘/ssh:phone#8022:/tmp/ob-input-87lP37’, decode using ‘base64 -d >%s’ failed

根据错误信息很容易知道这是因为Tramp尝试往Termux的 /tmp 目录中写内容导致的。

你可能会觉得这很好解决,只需要改一下 tramp-connection-properties 向Tramp指明 tmpdir 的路径就行了,像这样:

(add-to-list 'tramp-connection-properties
             (list (regexp-quote "/ssh:phone#8022:")
                   "tmpdir" "/data/data/com.termux/files/usr/tmp"))

然而很可惜,你会发现这样是没用的。这其实是 org-babel 中的一个 BUG(可以参见这里的讨论)

你需要修改 org-babel-remote-temporary-directory 的值指向新的路径.

我们首先看一下 Termux 中定义的 tmpdir 是哪个路径

echo $TMPDIR
/data/data/com.termux/files/usr/tmp

然后将其设置为 org-babel-remote-temporary-directory 的值

(set-default 'org-babel-remote-temporary-directory "/data/data/com.termux/files/usr/tmp")

这里有一点需要注意,那就是由于ob-shell在执行时不是在当前buffer中执行的,因此你通过 file-variable 机制将其临时修改为其他值是不顶用的. 这也是这里使用 set-default 进行赋值的原因