Como posso dizer ao TRAMP do Emacs para usar argumentos específicos para o ssh?

6

Estou tentando configurar meu Emacs TRAMP para acessar arquivos remotos via ssh, e gostaria de adicionar alguns argumentos adicionais ao comando ssh que o tramp usa para se conectar. Existe uma maneira de fazer isso?

Eu poderia fazer isso manipulando diretamente a variável tramp-methods , mas isso é nojento.

    
por Ryan Thompson 30.11.2010 / 22:57

2 respostas

5

Eu criei minha própria solução, mas é um pouco complicado demais para postar aqui. Se alguém estiver interessado, por favor, comente esta resposta, e eu vou encontrar um lugar para postá-lo.

Edit: Aqui está a minha solução, conforme solicitado.

Agora, configure algumas funções para anexar às listas de argumentos internas armazenadas em 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))))))

Finalmente, use tramp-add-args para adicionar os argumentos que você quer a todos os métodos baseados em 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")))

ronda de bónus

O código que mostro acima configura o compartilhamento de conexão para o ssh. Se você quer que isso funcione de forma confiável, você precisa limpar os arquivos de soquete quando a conexão com a Internet cair. O seguinte pode realizar isso

Primeiro, crie um script chamado ssh-cleanup e coloque-o no seu $PATH e coloque o seguinte:

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

Este script limpa os arquivos de controle obsoletos, pois eles serão deixados para trás quando o ssh for interrompido porque você desconectou o cabo de rede ou desconectou a rede sem fio.

Agora, configure o emacs para executar este script na hora apropriada:

(defun ssh-cleanup ()
  (ignore-errors
    (call-process "ssh-cleanup")))

(defadvice tramp-cleanup-all-connections (after cleanup-control-files activate)
  (ssh-cleanup))

Agora, quando você executar tramp-cleanup-all-connections , você também limpará o diretório do soquete ssh. Você deve executar isso sempre que desconectar e reconectar-se à Internet.

Você também pode configurar seu computador para fazer isso automaticamente.

Rodada Super Bonus

Se você usa o Network Manager no Linux, pode fazer com que o emacs faça coisas para você quando se conectar ou desconectar.

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

Agora, adicione o conjunto tramp-cleanup-all-connections para ser executado quando você se desconectar.

(add-hook 'network-manager-disconnect-hook 'tramp-cleanup-all-connections)
    
por 12.12.2010 / 03:38
1

Para uso único, não consigo pensar em uma maneira conveniente.

Para uma configuração mais permanente, faça sua configuração no nível ssh (que tem o benefício adicional de trabalhar fora do Emacs também). Em seu ~/.ssh/config , defina um alias de host com opções adicionais e conecte-se ao alias com o Tramp. Por exemplo. em ~/.ssh/config :

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

Em seguida, abra /ssh:foo:/path/to/file no Emacs.

    
por 01.12.2010 / 01:22