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 12:12:56 +0100

Eli Zaretskii <[email-masked]> writes:

Hi Eli & Jordan,

>> As you see, it requires two changes, in esh-proc.el and tramp.el.
>
> I think both can be cherry-picked to emacs-26.

Done. The change in tramp.el needed some massage.

Jordan, could you pls test whether the changes I have applied to the
emacs-26 branch work for you? See attachment for the changes.

> But do you know why we need expand-file-name here at all?

Well, in Emacs 26 we couldn't adapt exec-path for remote
processes. This is available since Emacs 27 only.

> At the very least, the comment about start-process should be removed,
> I think.

Done.

>> > Btw, isn't it confusing that start-file-process needs only the "local"
>> > part of COMMAND?  Why cannot its handler DTRT internally instead?
>> 
>> What do you do, if COMMAND is another remote location than
>> default-directory?
>
> Why is that a problem?  We always run the process in
> default-directory, right?

I said "another *remote* location". I don't want to see

(let ((default-directory "/ssh:user@host:directory"))
  (start-file-process "foo" buffer
  "/ssh:another-user@another-host:foo"))

Of course one could raise an error. But usually, this construct doesn't
appear as direct as in the example.

I believe using a local name for PROGRAM isn't such a burden.

>> And more general, there could also be file names in the PROGRAM-ARGS
>> part of start-file-process. Who decides, which of them is a remote file
>> name to be stripped to the local part, and which offers remote file name
>> syntax to be used literally?
>
> the caller, of course.  But I'm not asking about arguments, I'm asking
> about PROGRAM, and only about it.

See above. I don't believe it would make the life easier for callers of
`start-file-process', if we would allow a remote file name for PROGRAM. 

>> That's why we have decided (long ago), to not allow remote arguments for
>> both start-file-process and process-file.
>
> At the very least, this should be prominently mentioned in the
> respective doc strings and in the ELisp manual.  As written now, this
> is entirely undocumented.  Moreover, the part about "the local part of
> default-directory" in the doc string and in the manual is confusing,
> because we have no description of what that means.  The only attempt
> of describing it, in file-local-name's doc string, viz.:
>
>   It returns a file name which can be used directly as argument of
>   ‘process-file’, ‘start-file-process’, or ‘shell-command’.
>
> is IMO unsatisfactory, because it describes how results could be used,
> not what they are.

The docstring speaks about.

--8<---------------cut here---------------start------------->8---
PROGRAM and PROGRAM-ARGS might be file names.  They are not
objects of file name handler invocation.
--8<---------------cut here---------------end--------------->8---

The Elisp manual speaks about. (info "(elisp) Asynchronous Processes")

--8<---------------cut here---------------start------------->8---
This function does not try to invoke file name handlers for PROGRAM
or for the rest of ARGS.
--8<---------------cut here---------------end--------------->8---

Best regards, Michael.

diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 94401c5daa..97170eb04b 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -279,11 +279,9 @@ eshell-gather-process-output
 	    (let ((process-connection-type
 		   (unless (eshell-needs-pipe-p command)
 		     process-connection-type))
-		  (command (file-local-name command)))
+		  (command (file-local-name (expand-file-name command))))
 	      (apply 'start-file-process
-		     (file-name-nondirectory command) nil
-		     ;; `start-process' can't deal with relative filenames.
-		     (append (list (expand-file-name command)) args))))
+		     (file-name-nondirectory command) nil command args)))
       (eshell-record-process-object proc)
       (set-process-buffer proc (current-buffer))
       (if (eshell-interactive-output-p)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 5fa9f9a44d..5302659b32 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -4580,10 +4580,11 @@ tramp-eshell-directory-change
 	       (or
 		;; When `tramp-own-remote-path' is in `tramp-remote-path',
 		;; the remote path is only set in the session cache.
+                ;; Use `path-separator' as it does eshell.
 		(tramp-get-connection-property
 		 (tramp-get-connection-process v) "remote-path" nil)
 		(tramp-get-connection-property v "remote-path" nil))
-	       ":"))
+	       path-separator))
 	  (getenv "PATH"))))
 
 (eval-after-load "esh-util"