Open blurgyy opened 2 years ago
As far as I understand, you have a shell with, say, NEW_ENV="hello"
set. You then attach to a pre-existing zellij session and expect zellij to apply that environment variable to every new pane you open from now on through this client?
That would probably be a bit confusing because you have to remember which panes have which environment as old panes already open still have the original server environment?
Can you elaborate on the use case?
Hi @raphCode, thanks for the reply.
As far as I understand, you have a shell with, say,
NEW_ENV="hello"
set. You then attach to a pre-existing zellij session and expect zellij to apply that environment variable to every pane you open from now on through this client?
No, I'm aware of that expecting zellij to change an existing shell's environments is indeed confusing, and that's not what I would expect, either.
Edit(I misunderstood the above question): Yes, I am requesting zellij to apply/merge the environments of the client to newly created panes/tabs ever since I attach this client to an existing zellij session.
Can you elaborate on the use case?
The specific use case is: when I open a new pane/tab, I would like to be able to tell if I am in an SSH connection or not, by examining the shell environment in new pane/tab. This is the behaviour of TMUX and it would be great if zellij can make this configurable (I don't know a way to make this configurable in TMUX, afaik this is a forced behaviour in TMUX).
To explain this, here is a screenshot of how TMUX (with completely default configuration) handles this:
where the 0-th pane (left) is opened locally, and the 1-st pane (right) is openned from an SSH connection.
Note how the shell prompts in the two panes differ where the prompt in the 1-st pane (right) shows my username and my machine's hostname since it's opened from within an SSH connection so the shell inherits the SSH connection's environment variables.
I hope this makes it clearer.
How is your shell configured in tmux @blurgyy?
Hi @a-kenji,
How is your shell configured in tmux @blurgyy?
If you are asking about the shell prompt, it is managed by starship, which is configured to show my username if any of SSH_TTY
, SSH_CONNECTION
or SSH_CLIENT
is set, and to show the machine's hostname if SSH_CONNECTION
is set:
Hi @blurgyy, I will rephrase my question: Did you configure your shell in tmux? (through default-shell)
No, I did not configure my shell in tmux in the first screenshot.
The first screenshot was taken after I deleted my ~/.config/tmux/tmux.conf
, and I just checked there is no other tmux configuration enabled (I don't have a ~/.tmux.conf
).
@blurgyy, Thank you! That means that your shell is running as a login shell, maybe that could explain the behaviour? I am not to sure if tmux is actually sharing all the environment variables with every window.
Do you see the same behaviour when setting the shell as an interactive shell in tmux?
Hi @a-kenji, thank you for your reply!
Do you see the same behaviour when setting the shell as an interactive shell in tmux?
Yes, I think so:
I followed https://wiki.archlinux.org/title/Tmux#Start_a_non-login_shell to launch a non-login shell with tmux, does a "non-login shell" here mean an "interactive shell"?
Some extra information:
tmux.conf
in use:set -g default-command "${SHELL}"
set tsess "main"
set default_wname "default"
set wname (date '+%b-%d,%H-%M-%S')
if not tmux has-session -t $tsess 2>/dev/null
# If session '$tsess' does not exist, create first
tmux start-server
tmux select-window -t $tsess:0 \; \
rename-window $default_wname
end
exec tmux new-session -t $tsess \; \
new-window -n $wname \; \
select-window -t $wname
@blurgyy, Thank you for checking! In that case it seems that tmux is indeed doing something special with the environment variables. This might warrant an option to include in zellij.
Cool, thanks for considering this!
Thanks for the detail! If I understand correctly, this is your setup:
┌─────────────────────┐
│ │ ┌───────────┐
│ ┌─────┐ ┌───────┐ │ ssh │ │
│ │local├─►│ zellij│◄─┼───────┤ machine B │
│ │term │ └───────┘ │ │ │
│ └─────┘ │ └───────────┘
│ machine A │
└─────────────────────┘
And you want zellij to pick up the environment from attached clients and apply it to newly opened panes.
I tested this, and indeed tmux does it, but only for some variables: https://github.com/tmux/tmux/blob/06869ff22fa9891c9633ce3e3efa77cac758b520/options-table.c#L746-L754
I still don't think this is a good idea because panes have different envs depending on who opened them and not based on who is using them. Also this leads to stale environments after the ssh connection closes and the clients go away.
But, if tmux does it, we might too...
+1 - I just ran into this issue where I have Neovim's clipboard setup to use OSC52 via SSH but pbcopy/pbpaste
otherwise.
If my zellij session was started in a local terminal, then I SSH into it, Neovim still think's I'm local.
+1 Forwarding SSH_AUTH_SOCK
and similar would be very useful!
I ran into this as well; here's my usecase and workaround:
I use waypipe to proxy my Wayland session when reattaching to persistent tmux/zellij sessions over SSH. This allows me to share the Wayland clipboard between the local and remote system in nvim and other applications. (OSC52 copy from the remote system has not worked for me with nvim+zellij+foot, and I occasionally need to proxy graphical applications over waypipe anyways).
With tmux, you can invoke tmux show-env $ENV_VAR
from within the tmux session to get the current value of environment variables from the outside. Waypipe sets the WAYLAND_DISPLAY
env var when it opens the SSH session, and I'll grab this updated value automatically.
In .zshrc:
function refresh {
if [ -n "$TMUX" ] && [ -n "$SSH_TTY" ] && [ -n "$WAYLAND_DISPLAY" ]; then
export $(tmux show-env WAYLAND_DISPLAY 2> /dev/null)
fi
}
function preexec {
refresh
}
In nvim:
function! TmuxWaylandRefresh()
if !empty($TMUX) && !empty($WAYLAND_DISPLAY)
let prev_display = $WAYLAND_DISPLAY
let display = split(system("tmux show-env WAYLAND_DISPLAY 2> /dev/null"), "=")[1][:-2]
let $WAYLAND_DISPLAY = display
"echom "Changed $WAYLAND_DISPLAY from " . prev_display . " to " . $WAYLAND_DISPLAY
endif
endfunction
if exists('$TMUX')
autocmd BufEnter,FocusGained * call TmuxWaylandRefresh()
endif
Since zellij doesn't provide a way to get updated env vars from outside the session, I had to get a bit creative.
When I SSH in, I first grab the value of WAYLAND_DISPLAY
and write it to a temp file before reattaching to the session.
waypipe ssh -t $HOSTNAME "zsh -c 'printenv WAYLAND_DISPLAY > /tmp/wayland_display && zellij -s persist || zellij a persist'"
I then use this file to update the environment variable.
In .zshrc:
function refresh {
if [ -n "$ZELLIJ" ] && [ -f /tmp/wayland_display ]; then
export WAYLAND_DISPLAY=$(< /tmp/wayland_display)
fi
}
function preexec {
refresh
}
In nvim:
function! UpdateWaylandDisplay()
if !empty($ZELLIJ)
let $WAYLAND_DISPLAY = readfile("/tmp/wayland_display", 1)[0]
endif
endfunction
(Ideally, I'd want to check if I'm in an SSH session with $SSH_TTY
, but I haven't bothered with that for now.)
I think the request should be made clear here that this should be a manually curated list of environment variables that get updated on zellij attach. It should definitely not be all variables.
Ones that make sense: SSH_* parameters are an obvious ones DISPLAY is another (for ssh forwarded X) WAYLAND_DISPLAY
Currently the environment variables in shells opened in zellij are inherited from the session that starts the zellij server. It would be great to have the newly opened shells inherit the environment of the currently attached session. This is useful for, e.g., indicating current session is a SSH session via shell prompts.