UP | HOME |

Acceso remoto a un servidor vía ssh con Emacs

Acceso remoto a un servidor vía ssh con Emacs

Un anillo para gobernarlos a todos.
Un anillo para encontrarlos,
un anillo para atraerlos a todos
y atarlos en las tinieblas. – John Ronald Reuel Tolkien.

Rex Pelagius, Daniel Torres García.

Si deseamos trabajar con ficheros o programas alojados en un servidor de allí utilizando el entorno Emacs de aquí, basta con conectarse utilizando la propiedad Tramp. Por ejemplo, desde el Emacs del ordenador de aquí abro un fichero R en el servidor de allí, creo un proceso R allí y cualquier ejecución que ordene desde aquí se realiza allí.

Así, basta con que el ordenador de aquí contenga el programa Emacs configurado. Este Emacs local permite manejar otros servidores como si lo tuvieran instalado. Como requisito previo debe configurarse con ssh el servidor de allí.

Conexión ssh con Emacs

Para establecer una conexión ssh desde Emacs, incluimos el código del final de esta página en el fichero de inicio de Emacs y ejecutamos la siguiente instrucción en el Emacs de aquí:

M-x ssh-etm RET 192.168.1.37

Se abre una ventana Shell del equipo de allí. Cualquier operación que hagamos desde esa ventana, como abrir fichero, listar directorios, etc., se ejecuta allí. Los procesos, ficheros o buffers de allí se identifican con el modo menor Scp.

Ejemplo de conexión remota con Emacs

Aquí dispone de un ejemplo de cómo conseguir desde aquí una sesión interactiva con un proceso R que se ejecuta en el servidor de allí.

Abrir ficheros remotos

Aunque resulta más útil y cómodo acceder mediante ssh-etm, detallamos la forma tradicional de abrir un fichero remoto. C-x C-f abre un fichero. El siguiente ejemplo abre un fichero en un servidor remoto con permisos de superusuario.

/ssh:enano@192.168.1.101|sudo::enano@192.168.1.101:/usr/share/applications/scangear.desktop

Otras posibles configuraciones y métodos de Tramp se resumen a continuación.


/sudo::/path/to/file # sudo
/ssh:user@host:/path/to/file. # ssh
/plink:user@host:/path/to/file. # On MS Windows, PuTTY is often used as SSH client.
/smb:user%domain@host:/path/to/file. # Remote MS Windows host or Samba server,
/dav:user@host:/path/to/file # Virtual file system for the Gnome Desktop (GVFS)
/gdrive:john.doe@gmail.com:/path/to/file. # Google drive
/adb::/path/to/file. # Android

Código

Descargue el fichero fuente.

;;; ssh-etm.el --- Remote access via ssh             -*- lexical-binding: t; -*-

;; Copyright (C) 2020  emilio

;; Author: emilio <torres ../AT/.. uniovi.es>
;; Keywords: tools

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; M-x ssh-etm RET 192.168.1.37 

;;; Code:

;;; Using ssh to open a remote shell

;; Save ssh history
(defvar ssh-etm-history nil) ;
(eval-after-load "savehist"
  '(add-to-list 'savehist-additional-variables 'ssh-etm-history))

;; Based on http://stackoverflow.com/questions/1134149/emacs-remote-shell
(defun ssh-etm (&optional host)
  "Open a remote shell to a HOST."
  (interactive)
  (with-temp-buffer
    (let ((host (if host
                    host
                  (read-from-minibuffer "Host: " nil nil nil 'ssh-etm-history))))
      (cd (concat "/scp:" host ":"))
      (shell (concat "*" host "*")))))

;; notice password prompts and turn off echoing for them
(add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt)

;;; Identify remote files with minor mode Scp

(define-minor-mode scp-etm-mode
  "A mode to identify remote files"
  ;; The initial value.
  nil
  ;; The indicator for the mode line.
  " Scp")

(defvar scp-etm-mode-hook nil)

;; Based on http://stackoverflow.com/questions/13945782/emacs-auto-minor-mode-based-on-extension
(defun enable-minor-scp-etm-mode ()
  "Check file name against `^/scp:' to enable minor mode Scp"
  (interactive)
  (when buffer-file-name
    (let ((name buffer-file-name)
          (remote-id (file-remote-p buffer-file-name))
          (alist '(("^/scp:" . scp-etm-mode))))
      ;; Remove backup-suffixes from file name.
      (setq name (file-name-sans-versions name))
      ;; With remote files
      (when (and (stringp remote-id)
                 (string-match-p (regexp-quote remote-id) name))
        (while (and alist (caar alist) (cdar alist))
          (if (string-match (caar alist) name)
              (funcall (cdar alist) 1))
          (setq alist (cdr alist)))))))

(add-hook 'find-file-hook 'enable-minor-scp-etm-mode)

(provide 'ssh-etm)
;;; ssh-etm.el ends here