Как я могу сказать Emacs TRAMP использовать определенные аргументы для ssh?

1973
Ryan Thompson

Я пытаюсь настроить Emacs TRAMP для доступа к удаленным файлам через ssh, и я хотел бы добавить некоторые дополнительные аргументы в команду ssh, которую tramp использует для подключения. Есть ли способ сделать это?

Я мог бы сделать это, непосредственно манипулируя переменной tramp-methods, но это странно.

6

2 ответа на вопрос

5
Ryan Thompson

Я придумал собственное решение, но это слишком сложно, чтобы публиковать здесь. Если кому-то интересно, прокомментируйте этот ответ, и я найду где-нибудь его опубликовать.


Изменить: вот мое решение, как и просили.

Теперь настройте некоторые функции для добавления во встроенные списки аргументов, хранящиеся в tramp-methods:

(defun tramp-get-method-parameter (method param) "Return the method parameter PARAM. If the `tramp-methods' entry does not exist, return NIL." (let ((entry (assoc param (assoc method tramp-methods)))) (when entry (cadr entry))))  (defun tramp-set-method-parameter (method param newvalue) "Set the method paramter PARAM to VALUE for METHOD.  If METHOD does not yet have PARAM, add it. If METHOD does not exist, do nothing." (let ((method-params (assoc method tramp-methods))) (when method-params (let ((entry (assoc param method-params))) (if entry (setcar (cdr entry) newvalue) (setcdr (last method-params) '(param newvalue)))))))  (defun tramp-add-args (programs newargs) "Append NEWARGS to the argument list for any of PROGRAMS in `tramp-methods'.  PROGRAMS can be a list of strings, or a single string." ;; Allow a single program string or a list of matching programs. (when (stringp programs) (setq programs (list programs))) (message "%s" (list programs newargs)) (loop for method in (mapcar 'car tramp-methods) do (let ((login-program (tramp-get-method-parameter method 'tramp-login-program)) (copy-program (tramp-get-method-parameter method 'tramp-copy-program)) (login-args (tramp-get-method-parameter method 'tramp-login-args)) (copy-args (tramp-get-method-parameter method 'tramp-copy-args))) (message "Handling %s" method) (message " Handling login program %s" login-program) (when (find login-program programs :test 'string=) (message " Adding to login program %s" login-program) (tramp-set-method-parameter method 'tramp-login-args (append login-args newargs))) (message " Handling copy program %s" login-program) (when (find copy-program programs :test 'string=) (message " Adding to copy program %s" copy-program) (tramp-set-method-parameter method 'tramp-copy-args (append copy-args newargs)))))) 

Наконец, используйте, tramp-add-argsчтобы добавить аргументы, которые вы хотите, ко всем ssh-основанным методам:

(tramp-add-args '("scp" "scp1" "scp2" "scp1_old" "scp2_old" "sftp" "rsync" "ssh" "ssh1" "ssh2" "ssh1_old" "ssh2_old" "scpx" "sshx") '(("-o" "ControlPath=~/.ssh/control/emacs-master-%%r@%%h:%%p" "-o" "ControlMaster=auto"))) 

Бонус Раунд

Код, который я показываю выше, настраивает совместное использование соединения для ssh. Если вы хотите, чтобы это работало надежно, вам нужно очистить файлы сокетов, когда ваше интернет-соединение оборвется. Следующие могут сделать это

Сначала создайте скрипт с именем, ssh-cleanupпоместите его в свой $PATHи вставьте в него следующее:

#!/bin/sh CONTROL_DIR="$HOME/.ssh/control" find "$CONTROL_DIR" -type s | xargs --no-run-if-empty -- rm -f 

Этот сценарий очищает устаревшие управляющие файлы, так как они останутся позади, когда ssh умрет, потому что вы отключили сетевой кабель или отключили беспроводную связь.

Теперь настройте emacs для запуска этого скрипта в подходящее время:

(defun ssh-cleanup () (ignore-errors (call-process "ssh-cleanup")))  (defadvice tramp-cleanup-all-connections (after cleanup-control-files activate) (ssh-cleanup)) 

Теперь, когда вы запустите tramp-cleanup-all-connections, вы также очистите каталог сокета ssh. Вы должны запускать это всякий раз, когда вы отключаетесь и снова подключаетесь к Интернету.

Или вы можете настроить свой компьютер, чтобы сделать это для вас автоматически.

Супер Бонус Раунд

Если вы используете Network Manager в Linux, вы можете заставить emacs делать что-то для вас, когда вы подключаетесь или отключаетесь.

(defcustom network-manager-connect-hook nil "List of functions to execute upon successful establishment of a network connection." :type 'hook :group 'network-manager)  (defcustom network-manager-disconnect-hook nil "List of functions to execute upon disconnection from the network." :type 'hook :group 'network-manager)  ;; Only enable all of this if dbus is found (when (require 'dbus nil nil)  (defun network-manager-dbus-signal-handler (nmstate) "Execute the appropriate hook when Network Manager connects or disconnects." (case nmstate ((4 1) (run-hooks 'network-manager-disconnect-hook)) (3 (run-hooks 'network-manager-connect-hook))))  (defvar network-manager-dbus-registration nil)  (defun network-manager-integration-enable () (interactive) (network-manager-integration-disable) ; Make sure to clean up first (setq network-manager-dbus-registration (dbus-register-signal :system "org.freedesktop.NetworkManager" "/org/freedesktop/NetworkManager" "org.freedesktop.NetworkManager" "StateChanged" 'network-manager-dbus-signal-handler)))  (defun network-manager-integration-disable () (interactive) (when network-manager-dbus-registration (dbus-unregister-object network-manager-dbus-registration) (setq network-manager-dbus-registration nil)))  ;; Finally, enable it (network-manager-integration-enable)) 

Теперь добавьте набор tramp-cleanup-all-connectionsдля запуска при отключении.

(add-hook 'network-manager-disconnect-hook 'tramp-cleanup-all-connections) 
Да, пожалуйста. IIRC Я взглянул на код Трампа, и он грязный, но он все еще должен быть выполним в <100 строк Elisp, не слишком много, чтобы публиковать в ответе. Gilles 13 лет назад 0
1
Gilles

Для одноразового использования я не могу придумать удобный способ.

Для более постоянной настройки выполните настройку на уровне ssh (что также имеет побочную выгоду от работы вне Emacs). В вашем ~/.ssh/config, определите псевдоним хоста с дополнительными опциями и подключитесь к псевдониму с помощью Tramp. Например, в ~/.ssh/config:

Host foo HostName foo.example.com User rt ProxyCommand /usr/bin/nc -X connect -x proxy:3128 %h %p 

Затем откройте /ssh:foo:/path/to/fileв Emacs.

Ну, у меня есть некоторые опции ssh, которые я хочу использовать только в * emacs. Ryan Thompson 13 лет назад 0

Похожие вопросы