Subject: bug#71049: async-shell-command ends with "Process *Async Shell Command* finished" when remote "direct-async-process"

From: Michael Albinus <[email-masked]>
Date: Fri, 24 May 2024 18:39:21 +0200

Eli Zaretskii <[email-masked]> writes:

Hi Eli,

>> >> The command can be simple, like 'ls' or 'echo 123'. I also see this
>> >> added to *Messages*:
>> >>
>> >>   Tramp: Inserting
>> >>   ‘/ssh:[email-masked]:/home/d/dgutov/.tramp_history’...done
>> >
>> > According to reading .tramp_history: this is performed in
>> > comint-read-input-ring, called from shell-mode. comint-input-ring-file-name
>> > is set in shell-mode, I don't see a trivial solution to suppress
>> > this. Likely, we must extend shell-mode for this case.
>> 
>> We could add a user option remote-file-name-inhibit-input-ring which
>> suppresses reading the remote histfile, when set to non-nil. See
>> appended patch.
>> 
>> Eli?
>
> Can you explain the effect of that option on the scenarios that
> started this bug report?  I don't think I have a clear understanding
> of that.

We're speaking about shell-mode. Let's try the command

--8<---------------cut here---------------start------------->8---
(let ((default-directory "/ssh::"))
  (async-shell-command "ls"))
--8<---------------cut here---------------end--------------->8---

Tramp calls several initialization commands. In shell-mode, we see

--8<---------------cut here---------------start------------->8---
      (when remote
        ;; `shell-snarf-envar' does not work trustworthy.
        (setq hsize (shell-command-to-string "echo -n $HISTSIZE")
              hfile (shell-command-to-string "echo -n $HISTFILE")))
--8<---------------cut here---------------end--------------->8---

This triggers the commands in Tramp

--8<---------------cut here---------------start------------->8---
18:18:41.784634 tramp-send-command (6) # ( cd /home/albinus/ && env INSIDE_EMACS\=30.0.50\,tramp\:2.7.1-pre /bin/sh -c echo\ -n\ \$HISTSIZE </dev/null; echo tramp_exit_status $? )
18:18:41.817091 tramp-wait-for-regexp (6) # 
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:20:03.211358 tramp-send-command (6) # ( cd /home/albinus/ && env INSIDE_EMACS\=30.0.50\,tramp\:2.7.1-pre /bin/sh -c echo\ -n\ \$HISTFILE </dev/null; echo tramp_exit_status $? )
18:20:03.247281 tramp-wait-for-regexp (6) # 
~/.tramp_history
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
--8<---------------cut here---------------end--------------->8---

Two roundtrips. In

--8<---------------cut here---------------start------------->8---
      (setq comint-input-ring-file-name
            (concat
             remote
	     (or hfile
		 (cond ((string-equal shell "bash") "~/.bash_history")
		       ((string-equal shell "ksh") "~/.sh_history")
		       ((string-equal shell "zsh") "~/.zsh_history")
		       (t "~/.history")))))
--8<---------------cut here---------------end--------------->8---

we know, that comint-input-ring-file-name is
"/ssh:gandalf:~/.tramp_history". Next is

--8<---------------cut here---------------start------------->8---
      (if (or (equal comint-input-ring-file-name "")
	      (equal (file-truename comint-input-ring-file-name)
		     (file-truename null-device)))
--8<---------------cut here---------------end--------------->8---

which results in another roundtrip for file-truename.

--8<---------------cut here---------------start------------->8---
18:23:32.705940 tramp-send-command (6) # (if test -h "/home/albinus/.tramp_history"; then echo t; else echo nil; fi) && \readlink --canonicalize-missing /home/albinus/.tramp_history 2>/dev/null; echo tramp_exit_status $?
18:23:32.736575 tramp-wait-for-regexp (6) # 
nil
/home/albinus/.tramp_history
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
--8<---------------cut here---------------end--------------->8---

And finally, the history file is inserted into a buffer by the call of

--8<---------------cut here---------------start------------->8---
(comint-read-input-ring t)
--8<---------------cut here---------------end--------------->8---

which gives us another 6 roundtrips.

--8<---------------cut here---------------start------------->8---
18:26:07.617089 tramp-send-command (6) # test -r /home/albinus/.tramp_history 2>/dev/null; echo tramp_exit_status $?
18:26:07.649035 tramp-wait-for-regexp (6) # 
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:26:07.651779 tramp-send-command (6) # test -e /home/albinus/.cache/emacs/ 2>/dev/null; echo tramp_exit_status $?
18:26:07.658773 tramp-wait-for-regexp (6) # 
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:26:07.659542 tramp-send-command (6) # test -w /home/albinus/.cache/emacs/ 2>/dev/null; echo tramp_exit_status $?
18:26:07.724554 tramp-wait-for-regexp (6) # 
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:26:07.726639 tramp-send-command (6) # (if test -h "/home/albinus/.tramp_history"; then echo t; else echo nil; fi) && \readlink --canonicalize-missing /home/albinus/.tramp_history 2>/dev/null; echo tramp_exit_status $?
18:26:07.761576 tramp-wait-for-regexp (6) # 
nil
/home/albinus/.tramp_history
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:26:07.805806 tramp-send-command (6) # tramp_stat_file_attributes_with_selinux /home/albinus/.tramp_history 2>/dev/null; echo tramp_exit_status $?
18:26:07.839830 tramp-wait-for-regexp (6) # 
(("‘/home/albinus/.tramp_history’") 1 ("albinus" . 1000) ("albinus" . 1000) 1716544239 1715267567 1715267567 20671 "-rw-------" t 10891213 -1 "unconfined_u:object_r:user_home_t:s0")
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
///1ab1c259aca5ea2a0696680da9e7ac35#$
18:26:07.955777 tramp-send-command (6) # (env GZIP= gzip </home/albinus/.tramp_history | base64) 2>/dev/null; echo tramp_exit_status $?
18:26:07.991862 tramp-wait-for-regexp (6) # 
H4sIAO/nPGYAA+1XbVPbRhD+rl+xPdTYnsSVCcEBC5JShwSmpGF4yTRTNUaWTljDWRLSCZMp8Nu7
...
tramp_exit_status 0
///1ab1c259aca5ea2a0696680da9e7ac35#$
--8<---------------cut here---------------end--------------->8---

6 roundtrips to insert the remote history file into a buffer which we
don't need. Just for a single asynchronous "ls" command.

With the new user option, this could be avoided by a user setting.

> Why is the process being called by such bogus names anyway?

I don't understand. Which bogus names?

Best regards, Michael.