7

Several questions, including this one, discuss aspects relating to ssh connections from within Emacs. I haven't found an answer to my question though: How can I ssh into a remote machine from within Emacs?

I do not wish to edit a file on the remote machine from within Emacs. I am aware of M-x shell which opens a shell on my local machine and I am aware of using TRAMP to edit a file over ssh on the remote machine. However, neither of these relate to this question.

(Instead of voting to close, maybe migrate the question to another site.)

Edit: Related discussion here.

Community
  • 1
  • 1
SabreWolfy
  • 5,392
  • 11
  • 50
  • 73
  • Both `M-x shell` and Tramp *do* relate to your question as stated. So please explain concretely what it is that they don't do. I understand you want to do more than what Tramp lets you do, but what do you want to do that `M-x shell` doesn't let you do? – Stefan May 08 '12 at 16:08
  • I want to type `M-x ssh` or something similar to create an ssh connection, like I can type `M-x sql-postgresql` to create a connection directly to a database. `M-x shell` just opens a shell, from which I *can* ssh, or whatever. I was asking if there is a way to ssh *directly* from within Emacs. – SabreWolfy May 08 '12 at 16:25
  • What do you actually want to do over ssh that isn't editing remote files or opening up a remote terminal? – Tyler May 08 '12 at 17:46
  • I'm wanting to open up a remote terminal -- I want to ssh into a remote machine directly from Emacs, without using an external shell. If that's not possible, that's fine -- then that's the answer to the question. – SabreWolfy May 08 '12 at 18:01
  • Does this mean that the whole ssh focus of the question is a red herring, and all you want is a native shell inside Emacs (`eshell` as has been mentioned)? It sounds like the fact that you are then running ssh in that shell to connect to a remote machine is largely irrelevant? – phils May 08 '12 at 22:17
  • @phils: I want to know if I can run a native *ssh* directly from within Emacs, without having to launch a shell and then run ssh. Does Emacs directly provide an ssh client interface, like it does for sql connections (`M-x sql-postgres`)? – SabreWolfy May 09 '12 at 07:21
  • Sorry, but I'm still confused. How would the 'ssh client interface' differ from the using ssh in eshell, or shell-mode etc? Would writing a function that allowed you to enter 'M-x ssh', and have Emacs automatically open a shell-mode terminal (which is not an external shell, but lives in an Emacs buffer), and then fire up ssh (in that buffer) for you do what you want? That's easy to do, but if it's not what you're after I don't follow. – Tyler May 09 '12 at 15:26

4 Answers4

11

Firstly, I am unaware of a native elisp ssh client (and do not imagine there is a great deal of motivation for writing one), so you will certainly need to interact with an external ssh client process.

As you wish to use ssh interactively, the ssh process requires a terminal on the local side of the connection.

The question therefore becomes: Does Emacs implement a terminal to which an ssh process can be attached?

The answer is: yes -- term.el provides a robust terminal implementation, through which ssh can be run directly, without the requirement for a shell.

If you run M-x term RET you will be prompted for a program. (It defaults to a shell, but that is certainly not the only type of process you can run.)

For reasons unknown, the interactive term (and ansi-term) functions do not support passing arguments to the specified program, which renders them less useful if you wished to run something like ssh user@host. You could instead specify a script which handled the arguments, but we can manage that in elisp as well:

The term function is actually a simple wrapper which calls make-term to start the program and then sets the appropriate modes. As make-term does accept program arguments, it is quite straightforward to copy-and-modify the definition of term to suit your own purposes.

Here is a very simple implementation:

(defun my-ssh (user host port)
  "Connect to a remote host by SSH."
  (interactive "sUser: \nsHost: \nsPort (default 22): ")
  (let* ((port (if (equal port "") "22" port))
         (switches (list host "-l" user "-p" port)))
    (set-buffer (apply 'make-term "ssh" "ssh" nil switches))
    (term-mode)
    (term-char-mode)
    (switch-to-buffer "*ssh*")))

or perhaps this is preferable:

(defun my-ssh (args)
  "Connect to a remote host by SSH."
  (interactive "sssh ")
  (let ((switches (split-string-and-unquote args)))
    (set-buffer (apply 'make-term "ssh" "ssh" nil switches))
    (term-mode)
    (term-char-mode)
    (switch-to-buffer "*ssh*")))

Obviously there is scope for improvements, but I think that's fairly useful as-is.

You should ensure that you are familiar with the quirks of term-mode. See:

  • M-: (info "(emacs) Terminal emulator") RET
  • M-: (info "(emacs) Terminal Mode") RET
  • C-hf term-mode RET
phils
  • 71,335
  • 11
  • 153
  • 198
  • How do I specify the port? I made some modifications to your example, but I can't find where to specify the "-p PORT". I don't have the info pages, so I'll have to search for that elsewhere. – SabreWolfy May 13 '12 at 16:19
  • I've added a port argument. How did you install Emacs? Not having the info manuals available is a significant deficiency. – phils May 13 '12 at 22:37
  • Aside note: In Debian, the info pages are available under a difference license in package `emacs23-common-non-dfsg`. – SabreWolfy May 15 '12 at 19:08
  • 1
    n.b. for a slightly improved version of this code (adding a specific history, plus better buffer naming) see http://stackoverflow.com/a/19837365/324105 – phils Feb 09 '14 at 01:57
4

It turns out, there is what you want:

(setq rlogin-program "ssh")
(setq rlogin-process-connection-type t)

and then M-x rlogin RET <myhost> RET will do that.

Stefan
  • 27,908
  • 4
  • 53
  • 82
  • How do I specify username, password and port? Neither `M-x rlogin RET RET` nor `M-x rlogin RET RET` worked. http://emacswiki.org/emacs/RloginMode was not useful. – SabreWolfy May 12 '12 at 11:00
  • Those don't work because neither `ssh host username` nor `ssh username@host:port` are valid invocations. You can use `username@host -p port` or `host -l username -p port`. Or use `(setq rlogin-explicit-args '("-l" "username" "-p" "port"))`. You generally wouldn't need to specify a port at all, of course. Check `C-h f rlogin`. As `rlogin` uses `comint-mode`, you may also want `ansi-color-for-comint-mode-on` may also be useful. – phils May 12 '12 at 15:52
  • I'm finding the `term` approach with `term-char-mode` a little more solid than this. In particular, TAB completion in the remote shell works. When it comes to shells, `comint` seems more geared towards local than remote ones, whereas `term` doesn't make any such assumptions. – phils May 12 '12 at 16:07
  • The Emacs 24 bug with `rlogin-mode-map` is fixed in HEAD (or from 24.0.97), for anyone wondering about that. Here's the required diff if you want to patch it directly: http://bzr.savannah.gnu.org/lh/emacs/emacs-24/revision/107988/lisp/net/rlogin.el – phils May 12 '12 at 16:36
  • @phils: Thanks, I see that the format required is actually as the details should be passed to `ssh` directly. This worked and I was able to login to the machine. ANSI escape sequences are not appearing correctly, but I will refer to your answer as well. – SabreWolfy May 13 '12 at 16:14
2

Maybe ssh.el is what you are looking for. The ssh command provides a single-step way to create remote shells in Emacs via ssh, including specifying the user name in a natural way, and enabling tramp directory tracking if desired.

1

I'm not sure I understand. Open up M-x ansi-term and run ssh user@host there?

Mario
  • 1,801
  • 3
  • 20
  • 32
  • So Emacs itself doesn't have a shell program we should use? The solution is to simply make a shell (even with "M-x shell") and then just ssh in from there? I'm comparing it to Emacs SQL mode where Emacs itself makes the remote connection. – SabreWolfy May 08 '12 at 09:10
  • There is a shell, written in Elisp, called eshell, if that's what you mean. – Mirzhan Irkegulov May 08 '12 at 11:20
  • 1
    Correct, there are many shell implementations, but AFAIK there is no ssh client implementation. – Mario May 08 '12 at 11:20
  • @SabreWolfy No, Emacs DOES have a ssh/ftp wrapper called TRAMP, It takes care of connecting remote systems, sothat you can simply open remote files with `C-x C-f` as usual – kindahero May 08 '12 at 11:25
  • @kindahero: Yes, but I want to connect over ssh, not open remote files. – SabreWolfy May 08 '12 at 12:09