zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
20.68k stars 639 forks source link

zellij should launch the shell as a login shell #1434

Open hferreiro opened 2 years ago

hferreiro commented 2 years ago

I don't know if this is intended or not, but I noticed that when running tmux I have bash completions enabled, and with zellij they aren't. This looks to be enabled by loading /etc/profile at startup.

SpyrosRoum commented 2 years ago

I believe the shell is responsible for sourcing /etc/profile so I'm not sure how tmux or zellij are relevant, unless tmux loads it on its own for some reason.

You could try sourcing /etc/profile in your bashrc/zshrc maybe?

hferreiro commented 2 years ago

After some research I found that the issue is whether the shell is run as a login shell or an interactive shell. It appears that tmux runs bash as a login shell, and that's why /etc/profile is sourced. zellij appears to run bash as an interactive shell.

The consequence is surprising behavior as, for example, bash completion won't work when running zellij.

imsnif commented 2 years ago

Thanks for looking into this @hferreiro - I also agree this should be the behaviour (unless someone else is aware of a reason for this not to be?)

Putting a Help Wanted here in case anyone wants to work on this.

a-kenji commented 2 years ago

I also agree this should be the behaviour (unless someone else is aware of a reason for this not to be?)

By convention a login shell should by default be run once per login, unless explicitly specified by a user. It is used to automatically run programs that should only be run once per login. The interactive shell is used to run programs that should be run once per shell.

If we break with this convention users could have performance problems, or other unintended behaviors.

imsnif commented 2 years ago

Hmm - I see your point @a-kenji - I'm just wondering about the definition of a "login shell". When I open a new terminal emulator window, is it considered a login shell?

a-kenji commented 2 years ago

When I open a new terminal emulator window, is it considered a login shell?

It depends on what you configured your shell to be. On most systems it wouldn't and shouldn't be a login shell, at least by default. Because the commands that are sourced are by convention supposed to be run once, at the start of the login and not every time a new instance of the shell is opened.

If we ssh into a machine, then the login shell should be run exactly once - if the user wasn't logged in, but on opening a second pane it should open an interactive shell again.

imsnif commented 2 years ago

I see. This does check out with some local testing I've done. tmux does seem to open a login shell though (afaict in each separate pane according to shopt -q login_shell)... any guesses as to why?

hferreiro commented 2 years ago

gnome-terminal launches a login shell. I guess probably most terminal emulators, otherwise shell completion wouldn't work.

a-kenji commented 2 years ago

tmux does seem to open a login shell though (afaict in each separate pane according to shopt -q login_shell)... any guesses as to why?

No, I couldn't figure that out yet.

I have found this so far: https://www.gridbugs.org/daily/tmux-runs-a-login-shell-by-default/ https://www.gridbugs.org/make-sure-your-terminal-emulator-runs-in-the-expected-environment/

gnome-terminal launches a login shell. I guess probably most terminal emulators, otherwise shell completion wouldn't work.

@hferreiro, Not everyone uses /etc/profile as a location for completion. Completion works for me also in interactive shells. Also I doubt that gnome-terminal would launch a login shell.

I know for a fact that foot and alacritty don't spawn shells as a login shell.

Edit: It seems that gnome-terminal doesn't run a login shell by default: https://help.gnome.org/users/gnome-terminal/stable/pref-login-shell.html.en

hferreiro commented 2 years ago

My bad, you're right. It appears the completion being missing is because the system I use zellij in is Debian where /etc/profile.d/* isn't sourced by interactive shells, while on Fedora they are, and that's why I assumed that gnome-terminal run login shells.

imsnif commented 2 years ago

Cool, thanks for setting us straight @a-kenji ! So can we close this?

a-kenji commented 2 years ago

I think so?

There are legitimate reasons to run the shell as a login shell, but I think the user should opt in to that. Maybe we can add a way to surface this setting easily to a user.

hferreiro commented 2 years ago

I tried setting default_shell to -bash and bash --login but that failed.

a-kenji commented 2 years ago

@hferreiro, Yes, currently we only allow the path to a default shell. What you should be able to do is wrap your shell and then specify the path, but I can't try it out at the moment.

jcayzac commented 3 months ago

As a workaround I ended up writing this small bash-login wrapper script, which is in my $PATH. Don't forget to chmod +x it.

#!/usr/bin/env bash
exec /usr/bin/env -i HOME="$HOME" SHELL="$SHELL" PATH="$PATH" TERM="$TERM" USER="$USER" "$BASH" -il

…and in ~/.config/zellij/config.kdl:

default_shell "bash-login"
zachvalenta commented 2 months ago

There are legitimate reasons to run the shell as a login shell, but I think the user should opt in to that. Maybe we can add a way to surface this setting easily to a user.

@a-kenji Just an upvote for this. I want my .zprofile sourced on shell init otherwise I'm losing my prompt/aliases/env var.

@imsnif Could this be worked around by adding a new CLI or config option to enable running command(s) on pane startup (in my case,source $HOME/.zprofile)

zachvalenta commented 2 months ago

I tried to work around this with pane commands but no luck, as the source command was not available:

layout {
    pane
    pane split_direction="vertical" {
        pane command="source" {
            args "$HOME/.zprofile"
        }
    }
}

Some UNIX commands were available, however, like echo:

layout {
    pane
    pane split_direction="vertical" {
        pane command="echo" {
            args "hello"
        }
    }
}
jokeyrhyme commented 2 months ago

I spent a more time than I'd like to admit trying to make the concept of "login shell" useful on my system, and came to the conclusion that it's practically worthless, due to inconsistencies in how the user's SHELL is called by the various components that start it: https://gitlab.com/jokeyrhyme/dotfiles/-/issues/129#note_1575856312

This is in no way the fault of zellij, but we cannot depend on exactly one login shell per user session, because it might never run, and it might run more than once

I'd recommend removing any assumption about login shells from your configuration completely, and coming up with an alternative mechanism for guaranteeing that something happens exactly once per user session

Either that, or making such configuration idempotent so that it can be run every time your shell launches without breaking anything

zachvalenta commented 2 months ago

coming up with an alternative mechanism for guaranteeing that something happens exactly once per user session

To be clear, what I'm going for is the option to use login shells in new panes/tabs in the manner of tmux, iTerm, et al.

zachvalenta commented 2 months ago

I got around this by sourcing my profile in .zshenv, although the downside is that now my profile is being sourced twice when I'm outside Zellij.