Subject: bug#65551: 29.1; Eshell on MS-Windows using plink: 'plink' is not recognized as an internal or external command...

From: Jordan Wilson <[email-masked]>
Date: Sat, 26 Aug 2023 15:11:53 +0100

Hi all,

I've found a bug in Eshell on MS-Windows on 29.1. This is a regression
from 28.2. When connected to a remote machine using putty's "plink",
using any commands on the remote machine (e.g. not built-in to eshell)
prints this error in the eshell buffer (details replaced):

plink -l username -ssh -t example.com " env 'TERM=dumb'
'PROMPT_COMMAND=' 'PS1=#$ ' /bin/sh -i " ** exit || exit
'plink' is not recognised as an internal or external command, operable
program or batch file.

and the following in the minibuffer:
Tramp failed to connect.  If this happens repeatedly, try
    "M-x tramp-cleanup-this-connection"

An keyboard input after this causes the eshell buffer to be killed, and the
"Tramp failed to connect..." message to also be inserted into the next buffer.

Recipe, starting from "emacs -Q":
1) open eshell
2) connect to a remote host using plink
- cd /plink:[email-masked]:/home/username/
3) ./test.sh (executable script)
or...
3) *ls
or...
3) (any remote command not built-in into Emacs)

Below is the backtrace produced from this (using
`toggle-debug-on-error') again with details replaced.

Thanks,
Jordan.

Debugger entered--Lisp error: (file-error "Tramp failed to connect.  If this happens repeated...")
  signal(file-error ("Tramp failed to connect.  If this happens repeated..."))
  tramp-error(nil file-error "Tramp failed to connect.  If this happens repeated...")
  tramp-signal-hook-function(file-error ("Tramp failed to connect.  If this happens repeated..."))
  signal(file-error ("Tramp failed to connect.  If this happens repeated..."))
  tramp-maybe-open-connection((tramp-file-name #("plink" 0 5 (escaped t)) #("username" 0 5 (escaped t)) nil #("example.com" 0 18 (escaped t)) nil nil nil))
  tramp-send-command((tramp-file-name #("plink" 0 5 (escaped t)) #("username" 0 5 (escaped t)) nil #("example.com" 0 18 (escaped t)) nil nil nil) "echo $$ 2>/dev/null; echo tramp_exit_status $?")
  tramp-send-command-and-check((tramp-file-name #("plink" 0 5 (escaped t)) #("username" 0 5 (escaped t)) nil #("example.com" 0 18 (escaped t)) nil nil nil) "echo $$")
  tramp-barf-unless-okay((tramp-file-name #("plink" 0 5 (escaped t)) #("username" 0 5 (escaped t)) nil #("example.com" 0 18 (escaped t)) nil nil nil) "echo $$" "`%s' returns with error" "echo $$")
  tramp-send-command-and-read((tramp-file-name #("plink" 0 5 (escaped t)) #("username" 0 5 (escaped t)) nil #("example.com" 0 18 (escaped t)) nil nil nil) "echo $$")
  tramp-sh-handle-make-process(:name "test.sh" :buffer #<killed buffer> :command ("/home/username/test.sh") :filter eshell-output-filter :sentinel eshell-sentinel :connection-type nil :stderr nil :file-handler t)
  tramp-sh-file-name-handler(make-process :name "test.sh" :buffer #<killed buffer> :command ("/home/username/test.sh") :filter eshell-output-filter :sentinel eshell-sentinel :connection-type nil :stderr nil :file-handler t)
  apply(tramp-sh-file-name-handler make-process (:name "test.sh" :buffer #<killed buffer> :command ("/home/username/test.sh") :filter eshell-output-filter :sentinel eshell-sentinel :connection-type nil :stderr nil :file-handler t))
  tramp-file-name-handler(make-process :name "test.sh" :buffer #<killed buffer> :command ("/home/username/test.sh") :filter eshell-output-filter :sentinel eshell-sentinel :connection-type nil :stderr nil :file-handler t)
  eshell-gather-process-output("/plink:[email-masked]:/home/username/test.s..." nil)
  eshell-external-command("./test.sh" nil)
  eshell-plain-command("./test.sh" nil)
  eshell-named-command("./test.sh")
  eval((eshell-named-command '"./test.sh"))
  eshell-do-eval((eshell-named-command '"./test.sh") nil)
  eshell-do-eval((prog1 (eshell-named-command '"./test.sh") (mapc #'funcall eshell-this-command-hook)) nil)
  (condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"./test.sh") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1)))
  eval((condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"./test.sh") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))))
  eshell-do-eval((condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"./test.sh") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))) nil)
  #f(compiled-function () #<bytecode -0x12092870cc88ed70>)()
  funcall(#f(compiled-function () #<bytecode -0x12092870cc88ed70>))
  (let ((eshell-this-command-hook '(ignore))) (funcall '#f(compiled-function () #<bytecode -0x12092870cc88ed70>)))
  eval((let ((eshell-this-command-hook '(ignore))) (funcall '#f(compiled-function () #<bytecode -0x12092870cc88ed70>))))
  eshell-do-eval((let ((eshell-this-command-hook '(ignore))) (condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"./test.sh") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1)))) nil)
  eshell-do-eval((progn (let ((eshell-this-command-hook '(ignore))) (condition-case err (eshell-do-eval '(prog1 (eshell-named-command ...) (mapc ... eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))))) nil)
  (catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook '...)) (condition-case err (eshell-do-eval '... nil) ((debug error) (mapc ... eshell-this-command-hook) (eshell-errorn ...) (eshell-close-handles 1))))) nil))
  eval((catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook ...)) (condition-case err (eshell-do-eval ... nil) (... ... ... ...)))) nil)))
  eshell-do-eval((catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook ...)) (condition-case err (eshell-do-eval ... nil) (... ... ... ...)))) nil)) nil)
  eshell-do-eval((progn 'nil (catch 'top-level (eshell-do-eval '(progn (let (...) (condition-case err ... ...))) nil)) (run-hooks 'eshell-post-command-hook)) nil)
  #f(compiled-function () #<bytecode -0x12092870cc88ed70>)()
  funcall(#f(compiled-function () #<bytecode -0x12092870cc88ed70>))
  (let ((eshell-current-handles '[nil (t . 1) (t . 1)]) (eshell-current-subjob-p 'nil)) (funcall '#f(compiled-function () #<bytecode -0x12092870cc88ed70>)))
  eval((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) (eshell-current-subjob-p 'nil)) (funcall '#f(compiled-function () #<bytecode -0x12092870cc88ed70>))))
  eshell-do-eval((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) eshell-current-subjob-p) (progn 'nil (catch 'top-level (eshell-do-eval '(progn (let ... ...)) nil)) (run-hooks 'eshell-post-command-hook))))
  eshell-resume-eval()
  eshell-eval-command((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) eshell-current-subjob-p) (progn 'nil (catch 'top-level (eshell-do-eval '(progn (let ... ...)) nil)) (run-hooks 'eshell-post-command-hook))) "./test.sh ")
  eshell-send-input(nil)
  funcall-interactively(eshell-send-input nil)
  #<subr call-interactively>(eshell-send-input nil nil)
  call-interactively@ido-cr+-record-current-command(#<subr call-interactively> eshell-send-input nil nil)
  apply(call-interactively@ido-cr+-record-current-command #<subr call-interactively> (eshell-send-input nil nil))
  call-interactively(eshell-send-input nil nil)
  command-execute(eshell-send-input)

In GNU Emacs 29.1 (build 2, x86_64-w64-mingw32) of 2023-08-02 built on
 AVALON
Windowing system distributor 'Microsoft Corp.', version 10.0.19045
System Description: Microsoft Windows 10 Home (v10.0.2009.19045.3324)

Configured using:
 'configure --with-modules --without-dbus --with-native-compilation=aot
 --without-compress-install --with-tree-sitter CFLAGS=-O2'

Configured features:
ACL GIF GMP GNUTLS HARFBUZZ JPEG JSON LCMS2 LIBXML2 MODULES NATIVE_COMP
NOTIFY W32NOTIFY PDUMPER PNG RSVG SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XPM ZLIB

Important settings:
  value of $LANG: ENG
  locale-coding-system: cp1252

Major mode: Messages

Minor modes in effect:
  immortal-scratch-mode: t
  emms-mode-line-mode: t
  emms-playing-time-display-mode: t
  emms-playing-time-mode: t
  shell-dirtrack-mode: t
  recentf-mode: t
  global-anzu-mode: t
  anzu-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  winner-mode: t
  delete-selection-mode: t
  cua-mode: t
  ido-everywhere: t
  pdf-occur-global-minor-mode: t
  windmove-mode: t
  server-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: (only . t)
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

--
Jordan Wilson
    Sent from Gnus v5.13, GNU Emacs 29.1 on WINDOWS-NT