Wie kann ich Emacs TRAMP anweisen, bestimmte Argumente für ssh zu verwenden?

2162
Ryan Thompson

Ich versuche, meine Emacs TRAMP so einzurichten, dass sie über SSH auf entfernte Dateien zugreift, und ich möchte dem Befehl ssh, den Tramp für die Verbindung verwendet, einige zusätzliche Argumente hinzufügen. Gibt es eine Möglichkeit, dies zu tun?

Ich könnte es tun, indem ich die Variable direkt manipuliere tramp-methods, aber das ist icky.

6

2 Antworten auf die Frage

5
Ryan Thompson

Ich habe mir meine eigene Lösung ausgedacht, aber es ist zu kompliziert, hier zu posten. Wenn jemand interessiert ist, kommentieren Sie diese Antwort bitte, und ich werde irgendwo etwas finden, um sie zu posten.


Edit: Hier ist meine Lösung, wie gewünscht.

Richten Sie nun einige Funktionen zum Anhängen an die integrierten Argumentlisten ein, die in gespeichert sind 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)))))) 

Schließlich verwenden tramp-add-argsdie Argumente, die Sie wollen alle ssh-basierte Methoden hinzuzufügen:

(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"))) 

Bonusrunde

Der Code, den ich oben zeige, richtet die Verbindungsfreigabe für ssh ein. Wenn Sie möchten, dass dies zuverlässig funktioniert, müssen Sie die Socket-Dateien löschen, wenn Ihre Internetverbindung ausfällt. Folgendes kann dies erreichen

Erstellen Sie zuerst ein Skript mit dem Namen ssh-cleanupund fügen Sie es in Ihr ein. Fügen Sie $PATHFolgendes hinzu:

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

Dieses Skript bereinigt veraltete Kontrolldateien, da diese zurückbleiben, wenn ssh stirbt, weil Sie das Netzwerkkabel oder das Wireless-Kabel getrennt haben.

Richten Sie jetzt emacs ein, um dieses Skript zur richtigen Zeit auszuführen:

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

Beim Ausführen tramp-cleanup-all-connectionsbereinigen Sie jetzt auch das Ssh-Socket-Verzeichnis. Sie sollten dies ausführen, wenn Sie die Verbindung zum Internet trennen und wieder herstellen.

Oder Sie können Ihren Computer so einrichten, dass er dies automatisch für Sie erledigt.

Super Bonusrunde

Wenn Sie Network Manager unter Linux verwenden, können Sie sich von Emacs die Aufgabe stellen lassen, wenn Sie eine Verbindung herstellen oder trennen.

(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)) 

Fügen Sie nun das Set hinzu tramp-cleanup-all-connections, das ausgeführt werden soll, wenn Sie die Verbindung trennen.

(add-hook 'network-manager-disconnect-hook 'tramp-cleanup-all-connections) 
Ja, bitte mache es. IIRC Ich habe mir den Code von Tramp angeschaut und er ist chaotisch, aber er sollte in <100 Zeilen von Elisp noch machbar sein, nicht zu viel in einer Antwort. Gilles vor 13 Jahren 0
1
Gilles

Für eine einmalige Verwendung fällt mir kein bequemer Weg ein.

Für ein dauerhafteres Setup führen Sie Ihre Konfiguration auf der SSH-Ebene durch (was den Nebeneffekt hat, dass Sie auch außerhalb von Emacs arbeiten). ~/.ssh/configDefinieren Sie in Ihrem einen Host-Alias ​​mit zusätzlichen Optionen und stellen Sie mit Tramp eine Verbindung zum Alias ​​her. ZB in ~/.ssh/config:

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

Dann /ssh:foo:/path/to/filein Emacs öffnen .

Nun, ich habe einige ssh-Optionen, die ich nur innerhalb von * emacs verwenden möchte. Ryan Thompson vor 13 Jahren 0