Subject: bug#33791: 26.1; Eshell on Windows connecting to GNU/Linux machine using TRAMP and plink: env: ‘c:/home/jordan/test.sh’: No such file or directory

From: Michael Albinus <[email-masked]>
Date: Sat, 29 Dec 2018 10:14:05 +0100

Jordan Wilson <[email-masked]> writes:

Hi Jordan,

>> Can you provide a reproducing recipe starting from "emacs -Q"?
>
> - Have putty in $PATH (version 0.70 on my machine)
> - Load Eli's/Michael's patched files.el (error appears regardless)
>     (load "files.el")
> - M-x eshell
> - connect to GNU/Linux machine using plink:
>       /plink:[email-masked]:/home/jordan/
> - run executable in working directory
>       ./test.sh
> returns "env: ‘c:/home/jordan/test.sh’: No such file or directory"

I've tried to reproduce the problem with

--8<---------------cut here---------------start------------->8---
GNU Emacs 27.0.50 (build 1, x86_64-w64-mingw32)
 of 2018-10-05
--8<---------------cut here---------------end--------------->8---

This is the Emacs version offered on <https://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-27/>.

The error does not happen. Likely, this is due to the following commit:

--8<---------------cut here---------------start------------->8---
commit bbcd5787cb077f8b6c4eba5c1704ad953a298fd7
Author: Michael Albinus <[email-masked]>
Date:   Thu Mar 22 09:58:56 2018 +0100

    Fix commit c24c5dc4a4
    
    * lisp/net/tramp.el (tramp-handle-substitute-in-file-name): Drop volume
    letter of localname substitution.  Reported by Chris Zheng
    <[email-masked]>.
--8<---------------cut here---------------end--------------->8---

What happens, if you redefine tramp-handle-substitute-in-file-name after
loading Tramp?

--8<---------------cut here---------------start------------->8---

(defun tramp-handle-substitute-in-file-name (filename)
  "Like `substitute-in-file-name' for Tramp files.
\"//\" and \"/~\" substitute only in the local filename part."
  ;; Check, whether the local part is a quoted file name.
  (if (tramp-compat-file-name-quoted-p filename)
      filename
    ;; First, we must replace environment variables.
    (setq filename (tramp-replace-environment-variables filename))
    (with-parsed-tramp-file-name filename nil
      ;; We do not want to replace environment variables, again.  "//"
      ;; has a special meaning at the beginning of a file name on
      ;; Cygwin and MS-Windows, we must remove it.
      (let (process-environment)
	;; Ignore in LOCALNAME everything before "//" or "/~".
	(when (stringp localname)
	  (if (string-match "//\\(/\\|~\\)" localname)
	      (setq filename
                    (replace-regexp-in-string
                     "\\`/+" "/" (substitute-in-file-name localname)))
	    (setq filename
		  (concat (file-remote-p filename)
			  (replace-regexp-in-string
                           "\\`/+" "/"
			   ;; We must disable cygwin-mount file name
			   ;; handlers and alike.
			   (tramp-run-real-handler
			    'substitute-in-file-name (list localname))))))))
      ;; "/m:h:~" does not work for completion.  We use "/m:h:~/".
      (if (and (stringp localname) (string-equal "~" localname))
	  (concat filename "/")
	filename))))
--8<---------------cut here---------------end--------------->8---

Best regards, Michael.