7
votes

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.

4
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
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
What do you actually want to do over ssh that isn't editing remote files or opening up a remote terminal?Tyler
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
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

4 Answers

11
votes

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
4
votes

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.

2
votes

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
votes

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