Subject: Re: bug#66168: zsh home service breaks guix shell via ssh

From: Saku Laesvuori <[email-masked]>
Date: Mon, 25 Sep 2023 17:56:34 +0300

> > ```
> > $ ssh localhost
> > $ guix shell gnuplot
> > $ gnuplot
> > zsh: command not found: gnuplot
> > ```
> >
> > However (still within the ssh session)
> >
> > ```
> > $ guix shell gnuplot -- gnuplot
> > [gnuplot opens as expected]
> > ```
> >
> > and weirdly enough
> >
> > ```
> > $ guix shell --check gnuplot
> > guix shell: checking the environment variables visible from shell '/gnu/store/i4rj0banq044423if5xwb3df723g14r9-zsh-5.9/bin/zsh'...
> > guix shell: All is good!  The shell gets correct environment variables.
> > $ gnuplot
> > zsh: command not found: gnuplot
> > ```
> >
> > I don't really know what is happening here. Why does it work when
> > running the command directly and why does `guix shell --check` claim
> > that everything is correct when clearly something is wrong? If I
> > understand correctly `.zshenv` should be sourced in all these cases but
> > for some reason the problems only occur in some of them.
> >
> > Any ideas?
>
> My guess would be that sourcing /etc/profile should only happen once,
> but the SSH_CLIENT variable is inherited to the child shell which
> evaluates zshenv which in turn sources /etc/profile because SSH_CLIENT
> has non-zero length.  So /etc/profile is sourced twice.
> 
> This is just a wild guess though.

Seems to be about right. I had just assumed that guix shell would run
the command in a new shell (causing .zshenv to be sourced in all those
cases) but apparently it just calls the command directly. I haven't seen
any problems with sourcing /etc/profile multiple times because it
reloads both system and user profiles, but obviously it doesn't know
about guix shell profiles.

It seems that the default bash configuration only sources /etc/profile
if $SSH_CLIENT is non-empty and bash is used non-interactively.
Something similar could probably be done with zsh, but I would expect it
to still have this issue in certain situation. For example, I think
running a script like this

```
$ ssh host -- guix shell gnuplot <<EOF
...
EOF
```

would probably still fail.

I can't really think of any other possible solution than having an
environment variable that is set by /etc/profile and that makes sourcing
it a no-op.