Subject: Re: bug#70792: 30.0.50; [PATCH] Add Eshell support for expanding absolute file names within the current remote connection

From: Jim Porter <[email-masked]>
Date: Mon, 6 May 2024 11:13:20 -0700

On 5/6/2024 4:14 AM, Eli Zaretskii wrote:
> I don't understand how would this work conceptually.  Suppose I want
> to run a command on a remote host, but pipe the results into a command
> that runs locally -- how will Eshell know which file name to interpret
> relative to which directory, and how can the user indicate which is
> which unequivocally?

Thanks for taking a look. I'll try to explain this in more detail, since 
it's a fairly subtle interaction, especially if you don't use Tramp + 
Eshell heavily. (With the benefit of hindsight, we might have chosen not 
to handle remote access in Eshell the way it does, but it's now one of 
the big features users mention when they describe what they like about 
it. This patch is my best attempt at smoothing some of the existing 
rough edges here so that remote access in Eshell doesn't feel so 
capricious.)

Anyway...

File names are expanded according to the current working directory when 
you enter your command, so unless you explicitly type out the host in a 
file name, it's treated as belonging to the host associated with cwd. 
(If it helps, this is sort of like how "~" is expanded in regular 
shells. The shell expands it early on when parsing your input, so "sudo 
echo ~" outputs *your* homedir, not root's.)

Here are some examples with the new option enabled (note that "*" before 
a program name means "always execute the external program on the host"):

   ##### 1. Change to root
~ $ cd /sudo::
/sudo:root@host:~ # pwd; *pwd
/sudo:root@host:/root
/root

   ##### 2. Change to an absolute directory, stay as root
/sudo:root@host:~ # cd /etc; pwd; *pwd
/sudo:root@host:/etc
/etc

   ##### 3. Change to the home directory, stay as root
/sudo:root@host:~ # cd ~; pwd; *pwd
/sudo:root@host:/root
/root

   ##### 4. Write the expanded "~/foo.txt" to the *local* "~/bar.txt".
   ##### Using "/:" quoting lets you explicitly name a local file
/sudo:root@host:~ # *echo ~/foo.txt > /:~/bar.txt
/sudo:root@host:~ # cat bar.txt
/bin/cat: bar.txt: No such file or directory

   ##### 5. Change to the *local* home directory, stop being root
/sudo:root@host:~ # cd /:~; pwd; *pwd
/home/jim
/home/jim

   ##### 6. "bar.txt" ended up here
~ $ cat bar.txt
['-c', '/root/foo.txt']

In the last line above, note that the value we wrote to our file is just 
the local part. There's no Tramp remote host part here because Python 
(or other any other external program) wouldn't understand that syntax. 
Eshell strips off the remote part for you, unless you escape the 
argument, e.g. by surrounding it with quotes. (When doing this 
unexpanding, Eshell also makes sure that the remote host of the file 
name matches the host where the program will run.)

> IOW, I fear that this problem cannot be solved in principle in a
> shell-like application, and so trying to solve it will only cause us a
> terrible complexity mess.  What am I missing?

With this option *disabled* (the default), there are some problems that 
(in my opinion) make working with remote file names in Eshell even more 
complex. For example, suppose I'm on a remote host, and want to change 
to my home directory on that remote. There's not an easy way to do that:

   ##### 3b. Change to the home directory; stop being root(!)
/sudo:root@host:~ # cd ~; pwd; *pwd
/home/jim
/home/jim

Or suppose my cwd is /ssh:user@remote:/somedir. If I run "cat 
/etc/hosts", Eshell will print my local hosts file. But what if I run 
"cat -n /etc/hosts"? Eshell's "cat" implementation doesn't understand 
"-n", so it calls the "cat" on "remote". Now it prints the remote hosts 
file. You can only predict which hosts files you'll get if you know 
exactly which flags Eshell's "cat" implementation supports.