;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
-;; Copyright (C) 1998-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
;; (copyright statements below in code to be updated with the above notice)
:group 'tramp
:type 'string)
+;;;###tramp-autoload
+(defcustom tramp-histfile-override t
+ "When invoking a shell, override the HISTFILE with this value.
+When setting to a string, it redirects the shell history to that
+file. Be careful when setting to \"/dev/null\"; this might
+result in undesired results when using \"bash\" as shell.
+
+The value t, the default value, unsets any setting of HISTFILE,
+and sets both HISTFILESIZE and HISTSIZE to 0. If you set this
+variable to nil, however, the *override* is disabled, so the
+history will go to the default storage location,
+e.g. \"$HOME/.sh_history\"."
+ :group 'tramp
+ :version "25.1"
+ :type '(choice (const :tag "Do not override HISTFILE" nil)
+ (const :tag "Unset HISTFILE" t)
+ (string :tag "Redirect to a file")))
+
;;;###tramp-autoload
(defconst tramp-color-escape-sequence-regexp "\e[[;0-9]+m"
"Escape sequences produced by the \"ls\" command.")
,(format "TERM=%s" tramp-terminal-type)
"EMACS=t" ;; Deprecated.
,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
- "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=\"\""
+ "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat"
"autocorrect=" "correct=")
"List of environment variables to be set on the remote host.
(defconst tramp-perl-encode
"%s -e '
# This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015 Free Software Foundation, Inc.
use strict;
my %%trans = do {
(defconst tramp-perl-decode
"%s -e '
# This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015 Free Software Foundation, Inc.
use strict;
my %%trans = do {
(mapconcat 'identity (process-command p) " "))
(tramp-set-connection-property p "vector" orig-vec)
(tramp-compat-set-process-query-on-exit-flag p nil)
- (tramp-process-actions
- p v nil tramp-actions-copy-out-of-band)
+
+ ;; We must adapt `tramp-local-end-of-line' for
+ ;; sending the password.
+ (let ((tramp-local-end-of-line tramp-rsh-end-of-line))
+ (tramp-process-actions
+ p v nil tramp-actions-copy-out-of-band))
;; Check the return code.
(goto-char (point-max))
(name1 name)
(i 0)
;; We do not want to raise an error when
- ;; `start-file-process' has been started several time in
+ ;; `start-file-process' has been started several times in
;; `eshell' and friends.
(tramp-current-connection nil))
(tramp-send-command
vec
(format (concat "while read d; "
- "do if test -x $d/%s -a -f $d/%s; "
+ "do if test -x $d/%s && test -f $d/%s; "
"then echo tramp_executable $d/%s; "
"break; fi; done <<'%s'\n"
"%s\n%s")
;; when called as sh) on startup; this way, we avoid the startup
;; file clobbering $PS1. $PROMPT_COMMAND is another way to set
;; the prompt in /bin/bash, it must be discarded as well.
+ ;; $HISTFILE is set according to `tramp-histfile-override'.
(tramp-send-command
vec (format
- "exec env ENV='' HISTFILE=/dev/null PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s"
+ "exec env ENV='' %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s"
+ (if (stringp tramp-histfile-override)
+ (format "HISTFILE=%s"
+ (tramp-shell-quote-argument tramp-histfile-override))
+ (if tramp-histfile-override
+ "HISTFILE='' HISTFILESIZE=0 HISTSIZE=0"
+ ""))
(tramp-shell-quote-argument tramp-end-of-output)
shell (or extra-args ""))
t))
;; Therefore, we must remember the gateway vector. But we
;; cannot do it as connection property, because it shouldn't
;; be persistent. And we have no started process yet either.
- (tramp-set-file-property (car target-alist) "" "gateway" hop)))
+ (let ((tramp-verbose 0))
+ (tramp-set-file-property (car target-alist) "" "gateway" hop))))
;; Foreign and out-of-band methods are not supported for multi-hops.
(when (cdr target-alist)
(delete-process p))
(setenv "TERM" tramp-terminal-type)
(setenv "LC_ALL" "en_US.utf8")
- (setenv "HISTFILE" "/dev/null")
+ (if (stringp tramp-histfile-override)
+ (setenv "HISTFILE" tramp-histfile-override)
+ (if tramp-histfile-override
+ (progn
+ (setenv "HISTFILE")
+ (setenv "HISTFILESIZE" "0")
+ (setenv "HISTSIZE" "0"))))
(setenv "PROMPT_COMMAND")
(setenv "PS1" tramp-initial-end-of-output)
(let* ((target-alist (tramp-compute-multi-hops vec))
l-method 'tramp-connection-timeout))
(gw-args
(tramp-get-method-parameter l-method 'tramp-gw-args))
- (gw (tramp-get-file-property hop "" "gateway" nil))
+ (gw (let ((tramp-verbose 0))
+ (tramp-get-file-property hop "" "gateway" nil)))
(g-method (and gw (tramp-file-name-method gw)))
(g-user (and gw (tramp-file-name-user gw)))
(g-host (and gw (tramp-file-name-real-host gw)))
(setq login-args (append async-args login-args)))
;; Add gateway arguments if necessary.
- (when (and gw gw-args)
- (setq login-args (append gw-args login-args)))
+ (when gw
+ (tramp-set-connection-property p "gateway" t)
+ (when gw-args
+ (setq login-args (append gw-args login-args))))
;; Check for port number. Until now, there's no
;; need for handling like method, user, host.
(or (tramp-send-command-and-check vec command)
(apply 'tramp-error vec 'file-error fmt args)))
-(defun tramp-send-command-and-read (vec command &optional noerror)
+(defun tramp-send-command-and-read (vec command &optional noerror marker)
"Run COMMAND and return the output, which must be a Lisp expression.
+If MARKER is a regexp, read the output after that string.
In case there is no valid Lisp expression and NOERROR is nil, it
raises an error."
(when (if noerror
(tramp-barf-unless-okay
vec command "`%s' returns with error" command))
(with-current-buffer (tramp-get-connection-buffer vec)
- ;; Read the expression.
(goto-char (point-min))
+ ;; Read the marker.
+ (when (stringp marker)
+ (condition-case nil
+ (re-search-forward marker)
+ (error (unless noerror
+ (tramp-error
+ vec 'file-error
+ "`%s' does not return the marker `%s': `%s'"
+ command marker (buffer-string))))))
+ ;; Read the expression.
(condition-case nil
(prog1 (read (current-buffer))
;; Error handling.
"/bin:/usr/bin")
"/bin:/usr/bin"))))
(own-remote-path
- ;; We cannot apply `tramp-send-command-and-read' because
- ;; the login shell could return more than just the $PATH
- ;; string. So we emulate that function.
+ ;; The login shell could return more than just the $PATH
+ ;; string. So we use `tramp-end-of-heredoc' as marker.
(when elt2
- (tramp-send-command
+ (tramp-send-command-and-read
vec
(format
- "%s -l %s 'echo \\\"$PATH\\\"'"
+ "%s -l %s 'echo %s \\\"$PATH\\\"'"
(tramp-get-method-parameter
(tramp-file-name-method vec) 'tramp-remote-shell)
(mapconcat
'identity
(tramp-get-method-parameter
(tramp-file-name-method vec) 'tramp-remote-shell-args)
- " ")))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (goto-char (point-max))
- (forward-line -1)
- (read (current-buffer))))))
+ " ")
+ (tramp-shell-quote-argument tramp-end-of-heredoc))
+ nil (regexp-quote tramp-end-of-heredoc)))))
;; Replace place holder `tramp-default-remote-path'.
(when elt1