From: Michael Albinus Date: Fri, 20 Sep 2019 09:27:49 +0000 (+0200) Subject: Some Tramp methods allow to change the remote login shell X-Git-Tag: emacs-27.0.90~1538 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=828233009a8c8dcbf58a561ca8fd06bd53198974;p=emacs.git Some Tramp methods allow to change the remote login shell * doc/misc/tramp.texi (Inline methods) : (External methods) : Mention, that the remote login shell could be changed. (Remote shell setup): Remove description of properties "remote-shell-login" and "remote-shell-args", they don't matter here. Changing the default remote shell works only for some methods. (Frequently Asked Questions): Refer to alternative approach fixing zsh problems. * etc/NEWS: Some Tramp methods allow to change the remote login shell. * lisp/net/tramp-sh.el (tramp-default-remote-shell): New defconst. (tramp-methods): Use it. (tramp-get-sh-extra-args): New defun. (tramp-open-shell, tramp-maybe-open-connection): Use it. * lisp/net/tramp.el (tramp-methods): Adapt docstring. --- diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 1ed334b6bde..1440521df56 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -805,7 +805,8 @@ behavior. Works like @option{ssh} but without the extra authentication prompts. @option{sshx} uses @samp{ssh -t -t @var{host} -l @var{user} /bin/sh} -to open a connection with a ``standard'' login shell. +to open a connection with a ``standard'' login shell. It supports to +change the remote login shell @command{/bin/sh}. @strong{Note} that @option{sshx} does not bypass authentication questions. For example, if the host key of the remote host is not @@ -841,7 +842,8 @@ This is another method from the Kerberos suite. It behaves like @option{su}. @option{plink} method is for MS Windows users with the PuTTY implementation of SSH@. It uses @samp{plink -ssh} to log in to the -remote host. +remote host. It supports to change the remote login shell +@command{/bin/sh}. Check the @samp{Share SSH connections if possible} control for that session. @@ -854,7 +856,8 @@ session. Another method using PuTTY on MS Windows with session names instead of host names. @option{plinkx} calls @samp{plink -load @var{session} --t}. User names and port numbers must be defined in the session. +-t}. User names and port numbers must be defined in the session. It +supports to change the remote login shell @command{/bin/sh}. Check the @samp{Share SSH connections if possible} control for that session. @@ -928,7 +931,8 @@ This method supports the @samp{-p} argument. @option{scpx} is useful to avoid login shell questions. It is similar in performance to @option{scp}. @option{scpx} uses @samp{ssh -t -t -@var{host} -l @var{user} /bin/sh} to open a connection. +@var{host} -l @var{user} /bin/sh} to open a connection. It supports +to change the remote login shell @command{/bin/sh}. @option{scpx} is useful for MS Windows users when @command{ssh} triggers an error about allocating a pseudo tty. This happens due to @@ -952,6 +956,8 @@ use the @command{plink} command to connect to the remote host, and they use @command{pscp} or @command{psftp} for transferring the files. These programs are part of PuTTY, an SSH implementation for MS Windows. +They support to change the remote login shell @command{/bin/sh}. + Check the @samp{Share SSH connections if possible} control for that session. @@ -2100,12 +2106,10 @@ be recomputed. To force @value{tramp} to recompute afresh, call @cindex zsh setup Per default, @value{tramp} uses the command @command{/bin/sh} for -strting a shell on the remote host. This can be changed by setting +starting a shell on the remote host. This can be changed by setting the connection property @option{remote-shell}, see @xref{Predefined -connection information}. Other properties might be adapted as well, -like @option{remote-shell-login} or @option{remote-shell-args}. If -you want, for example, use @command{/usr/bin/zsh} on a remote host, -you might apply +connection information}. If you want, for example, use +@command{/usr/bin/zsh} on a remote host, you might apply @lisp @group @@ -2115,6 +2119,11 @@ you might apply @end group @end lisp +This works only for connection methods which allow to override the +remote login shell, like @option{sshx} or @option{plink}. See +@ref{Inline methods} and @ref{External methods} for connection methods +which support this. + This approach has also the advantage, that settings in @code{tramp-sh-extra-args} will be applied. For zsh, the trouble with the shell prompt due to set zle options will be avoided. @@ -3766,6 +3775,9 @@ This uses the default value of @code{tramp-terminal-type}, you want to use another value for @env{TERM}, change @code{tramp-terminal-type} and this line accordingly. +Alternatively, you could set the remote login shell explicitly. See +@ref{Remote shell setup} for discussing this technique, + When using fish shell on remote hosts, disable fancy formatting by adding the following to @file{~/.config/fish/config.fish}: diff --git a/etc/NEWS b/etc/NEWS index e0038e40845..c129e8a0b6e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1530,6 +1530,12 @@ names are adjusted to the host name from the previous hop. timeout, after which the underlying session is disabled. This is for security reasons. ++++ +*** For some connection methods, like "sshx" or "plink", it is +possible to configure the remote login shell. This avoids problems +with remote hosts, where "/bin/sh" is a link to a shell which +cooperates badly with Tramp. + ** Rcirc --- diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 8092f6a5cf1..b7089207cb1 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -37,6 +37,10 @@ (defvar vc-git-program) (defvar vc-hg-program) +;;;###tramp-autoload +(defconst tramp-default-remote-shell "/bin/sh" + "The default remote shell Tramp applies.") + ;;;###tramp-autoload (defcustom tramp-inline-compress-start-size 4096 "The minimum size of compressing where inline transfer. @@ -132,10 +136,10 @@ The string is used in `tramp-methods'.") ;;;###tramp-autoload (tramp--with-startup (add-to-list 'tramp-methods - '("rcp" + `("rcp" (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") @@ -143,35 +147,37 @@ The string is used in `tramp-methods'.") (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods - '("remcp" + `("remcp" (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") (tramp-copy-args (("-p" "%k"))) (tramp-copy-keep-date t))) (add-to-list 'tramp-methods - '("scp" + `("scp" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") - (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("%c"))) + (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") + ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods - '("scpx" + `("scpx" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) + ("-e" "none") ("-t" "-t") ("%h") + ("%l"))) (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") @@ -180,64 +186,66 @@ The string is used in `tramp-methods'.") (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods - '("rsync" + `("rsync" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rsync") - (tramp-copy-args (("-t" "%k") ("-p") ("-r") ("-s") ("-c"))) + (tramp-copy-args (("-t" "%k") ("-p") ("-r") ("-s") + ("-c"))) (tramp-copy-env (("RSYNC_RSH") ("ssh" "%c"))) (tramp-copy-keep-date t) (tramp-copy-keep-tmpfile t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods - '("rsh" + `("rsh" (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods - '("remsh" + `("remsh" (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods - '("ssh" + `("ssh" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods - '("sshx" + `("sshx" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) + ("-e" "none") ("-t" "-t") ("%h") + ("%l"))) (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods - '("telnet" + `("telnet" (tramp-login-program "telnet") (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods - '("nc" + `("nc" (tramp-login-program "telnet") (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "nc") @@ -247,24 +255,25 @@ The string is used in `tramp-methods'.") ;; We use "-p" as required for newer busyboxes. For older ;; busybox/nc versions, the value must be (("-l") ("%r")). This ;; can be achieved by tweaking `tramp-connection-properties'. - (tramp-remote-copy-args (("-l") ("-p" "%r") ("2>/dev/null"))))) + (tramp-remote-copy-args (("-l") ("-p" "%r") + ("2>/dev/null"))))) (add-to-list 'tramp-methods - '("su" + `("su" (tramp-login-program "su") (tramp-login-args (("-") ("%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) (add-to-list 'tramp-methods - '("sg" + `("sg" (tramp-login-program "sg") (tramp-login-args (("-") ("%u"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) (add-to-list 'tramp-methods - '("sudo" + `("sudo" (tramp-login-program "sudo") ;; The password template must be masked. Otherwise, ;; it could be interpreted as password prompt if the @@ -273,46 +282,47 @@ The string is used in `tramp-methods'.") ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":"))) ;; Local $SHELL could be a nasty one, like zsh or ;; fish. Let's override it. - (tramp-login-env (("SHELL") ("/bin/sh"))) - (tramp-remote-shell "/bin/sh") + (tramp-login-env (("SHELL") + (,tramp-default-remote-shell))) + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10) (tramp-session-timeout 300))) (add-to-list 'tramp-methods - '("doas" + `("doas" (tramp-login-program "doas") (tramp-login-args (("-u" "%u") ("-s"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10) (tramp-session-timeout 300))) (add-to-list 'tramp-methods - '("ksu" + `("ksu" (tramp-login-program "ksu") (tramp-login-args (("%u") ("-q"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) (add-to-list 'tramp-methods - '("krlogin" + `("krlogin" (tramp-login-program "krlogin") (tramp-login-args (("%h") ("-l" "%u") ("-x"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods `("plink" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") - ("%h") ("\"") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type tramp-initial-end-of-output)) - ("/bin/sh") ("\""))) - (tramp-remote-shell "/bin/sh") + ("%l") ("\""))) + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods @@ -323,50 +333,50 @@ The string is used in `tramp-methods'.") "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type tramp-initial-end-of-output)) - ("/bin/sh") ("\""))) - (tramp-remote-shell "/bin/sh") + ("%l") ("\""))) + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) (add-to-list 'tramp-methods `("pscp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") - ("%h") ("\"") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type tramp-initial-end-of-output)) - ("/bin/sh") ("\""))) - (tramp-remote-shell "/bin/sh") + ("%l") ("\""))) + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") - (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") ("-p" "%k") - ("-q") ("-r"))) + (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") + ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods `("psftp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") - ("%h") ("\"") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type tramp-initial-end-of-output)) - ("/bin/sh") ("\""))) - (tramp-remote-shell "/bin/sh") + ("%l") ("\""))) + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") - (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k") - ("-q"))) + (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") + ("-p" "%k") ("-q"))) (tramp-copy-keep-date t))) (add-to-list 'tramp-methods - '("fcp" + `("fcp" (tramp-login-program "fsh") (tramp-login-args (("%h") ("-l" "%u") ("sh" "-i"))) - (tramp-remote-shell "/bin/sh") + (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-i") ("-c")) (tramp-copy-program "fcp") @@ -778,7 +788,8 @@ my $data; while (read STDIN, $data, 54) { my $pad = q(); - # Only for the last chunk, and only if did not fill the last three-byte packet + # Only for the last chunk, and only if did not fill the last + # three-byte packet if (eof) { my $mod = length($data) %% 3; $pad = q(=) x (3 - $mod) if $mod; @@ -4023,19 +4034,22 @@ file exists and nonzero exit status otherwise." vec 'file-error "Couldn't find command to check if file exists")) result)) +(defun tramp-get-sh-extra-args (shell) + "Find extra args for SHELL." + (let ((alist tramp-sh-extra-args) + item extra-args) + (while (and alist (null extra-args)) + (setq item (pop alist)) + (when (string-match-p (car item) shell) + (setq extra-args (cdr item)))) + extra-args)) + (defun tramp-open-shell (vec shell) "Opens shell SHELL." (with-tramp-progress-reporter vec 5 (format-message "Opening remote shell `%s'" shell) ;; Find arguments for this shell. - (let ((alist tramp-sh-extra-args) - item extra-args) - (while (and alist (null extra-args)) - (setq item (pop alist)) - (when (string-match-p (car item) shell) - (setq extra-args (cdr item)))) - ;; It is useful to set the prompt in the following command - ;; because some people have a setting for $PS1 which /bin/sh + (let ((extra-args (tramp-get-sh-extra-args shell))) ;; doesn't know about and thus /bin/sh will display a strange ;; prompt. For example, if $PS1 has "${CWD}" in the value, then ;; ksh will display the current working directory but /bin/sh @@ -4894,6 +4908,9 @@ connection if a previous connection has died for some reason." (tramp-get-method-parameter hop 'tramp-login-program)) (login-args (tramp-get-method-parameter hop 'tramp-login-args)) + (remote-shell + (tramp-get-method-parameter hop 'tramp-remote-shell)) + (extra-args (tramp-get-sh-extra-args remote-shell)) (login-env (tramp-get-method-parameter hop 'tramp-login-env)) (async-args @@ -4971,7 +4988,8 @@ connection if a previous connection has died for some reason." spec (format-spec-make ?t tmpfile) options (format-spec options spec) spec (format-spec-make - ?h l-host ?u l-user ?p l-port ?c options) + ?h l-host ?u l-user ?p l-port ?c options + ?l (concat remote-shell " " extra-args)) command (concat ;; We do not want to see the trailing local @@ -5320,7 +5338,7 @@ Nonexistent directories are removed from spec." (progn (tramp-message vec 3 - "`getconf PATH' not successful, using default value \"%s\"." + "`getconf PATH' not successful, using default value \"%s\"." "/bin:/usr/bin") "/bin:/usr/bin")))) (own-remote-path @@ -5894,9 +5912,6 @@ function cell is returned to be applied on a buffer." ;; way of passing credentials, like by using an SSL socket or ;; something. (David Kastrup) ;; -;; * Reconnect directly to a compliant shell without first going -;; through the user's default shell. (Pete Forman) -;; ;; * Avoid the local shell entirely for starting remote processes. If ;; so, I think even a signal, when delivered directly to the local ;; SSH instance, would correctly be propagated to the remote process diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index aefb84bb4e4..934b5dd9d9f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -212,22 +212,32 @@ pair of the form (KEY VALUE). The following KEYs are defined: * `tramp-login-args' This specifies the list of arguments to pass to the above - mentioned program. Please note that this is a list of list of arguments, - that is, normally you don't want to put \"-a -b\" or \"-f foo\" - here. Instead, you want a list (\"-a\" \"-b\"), or (\"-f\" \"foo\"). - There are some patterns: \"%h\" in this list is replaced by the host - name, \"%u\" is replaced by the user name, \"%p\" is replaced by the - port number, and \"%%\" can be used to obtain a literal percent character. - If a list containing \"%h\", \"%u\" or \"%p\" is unchanged during - expansion (i.e. no host or no user specified), this list is not used as - argument. By this, arguments like (\"-l\" \"%u\") are optional. - \"%t\" is replaced by the temporary file name produced with - `tramp-make-tramp-temp-file'. \"%k\" indicates the keep-date - parameter of a program, if exists. \"%c\" adds additional - `tramp-ssh-controlmaster-options' options for the first hop. - The existence of `tramp-login-args', combined with the absence of - `tramp-copy-args', is an indication that the method is capable of - multi-hops. + mentioned program. Please note that this is a list of list + of arguments, that is, normally you don't want to put \"-a + -b\" or \"-f foo\" here. Instead, you want a list (\"-a\" + \"-b\"), or (\"-f\" \"foo\"). There are some patterns: + + - \"%h\" in this list is replaced by the host name + - \"%u\" is replaced by the user name + - \"%p\" is replaced by the port number + - \"%%\" can be used to obtain a literal percent character. + + If a list containing \"%h\", \"%u\" or \"%p\" is unchanged + during expansion (i.e. no host, no user or no port + specified), this list is not used as argument. By this, + arguments like (\"-l\" \"%u\") are optional. + + - \"%l\" is replaced by the login shell `tramp-remote-shell' + and its parameters. + - \"%t\" is replaced by the temporary file name produced with + `tramp-make-tramp-temp-file'. + - \"%k\" indicates the keep-date parameter of a program, if exists + - \"%c\" adds additional `tramp-ssh-controlmaster-options' + options for the first hop. + + The existence of `tramp-login-args', combined with the + absence of `tramp-copy-args', is an indication that the + method is capable of multi-hops. * `tramp-login-env' A list of environment variables and their values, which will @@ -327,6 +337,9 @@ inline method, then these two parameters should be nil. Notes: +All these arguments can be overwritten by connection properties. +See Info node `(tramp) Predefined connection information'. + When using `su' or `sudo' the phrase \"open connection to a remote host\" sounds strange, but it is used nevertheless, for consistency. No connection is opened to a remote host, but `su' or `sudo' is