[i3-discuss] Re: how to get new environment variables when restarting i3

  • From: frederik@xxxxxxx
  • To: i3-discuss@xxxxxxxxxxxxx
  • Date: Tue, 1 Jan 2019 14:22:09 -0800

For what with all the people who disagreed with me, I still found
myself wanting this feature (screen has setenv, so does tmux?). But I
found it was fairly easy to implement my desired behavior using Ingo's
hint about how i3 restarts. Looking at the code I saw that i3 does not
exec i3, it execs argv[0]. So by replacing argv[0] with a custom
script (via 'exec -a'), I can get it to source new environment
variables upon restart. Here is my script:

   $ cat =run-i3
   #!/bin/zsh

   (date; echo "$@") >> ~/.run-i3.log

   . ~/.zprofile

   exec -a $(which run-i3) i3 "$@"

I test that this works using a keybinding:

   $ grep /test .i3/config
   bindsym $mod+Mod4+n exec "sh -c 'echo $MYVAR > ~/test'"

I have to use a keybinding because "i3-msg exec" seems to take its
command environment from its own the environment rather than i3's.

Thanks for your help,

Frederick

On Sat, Jul 02, 2016 at 11:00:32PM +0200, Ingo Bürk wrote:

Hi,

I agree with what Bennett said. The profile files are meant to be
sourced on login and only on login. It sounds like you may want to make
changes to the zshrc instead? IMHO everything is working as intended here.

Personally, my bash_profile simply sources my bashrc. That isn't exactly
the intention either, but would cover your case.

It would be great if i3 had a way to save the layout between sessions.

The in-place restart i3 has dumps the layout to a temporary file and
passes the path to this file to the new i3 process. Given that this
restart is really the only usecase it's not a documented command-line
option, but in principle there's no reason why you couldn't use it
manually. I'm not recommending it, though.


Regards
Ingo

On 07/02/2016 10:51 PM, frederik@xxxxxxx wrote:
Thanks for your reply.

You want to change something in your .zprofile and have this change
propagated to terminals that are already running?
No, just newly-created terminals.

I wonder about how frequent such changes are and whether logging out and
back in is really such a big deal.
It's not a big deal, but the frequency of changes to .zprofile (adding
a new PATH component, etc.) is currently higher than the frequency of
changes to .i3/config. That means I use the "killall" solution more
often than mod+shift+r.

At worst it can cause your X server to shut down, for example
because you use xinit with i3 as the "keepalive" process.
Obviously, I do not do this. I see that the end of my .xinitrc is:

    i3 &
    sleep 1000d

It would be great if i3 had a way to save the layout between sessions.

Thanks,

Frederick

On Sat, Jul 02, 2016 at 02:42:56PM +0200, Ingo Bürk wrote:
Hi Frederick,

why do you want to change the environment i3 runs anyway? This doesn't
sound right to me. i3 simply passes commands to /bin/sh -c and I'm not
sure I understand the exact problem yet. You want to change something in
your .zprofile and have this change propagated to terminals that are
already running?

Doing "kilalll i3; i3" is possible in principle, but will at the very
least forget your entire layout. At worst it can cause your X server to
shut down, for example because you use xinit with i3 as the "keepalive"
process.

I wonder about how frequent such changes are and whether logging out and
back in is really such a big deal. I don't think we are going to want to
do anything within i3 itself for this because I just don't think it's
worth the complexity and maintenance effort. But perhaps I'm missing
something crucial to the usefulness of this.


Regards

Ingo

On 07/02/2016 02:17 AM, frederik@xxxxxxx wrote:
Dear i3-discuss,

I noticed that the i3 "restart" command is very quick and responsive.

However, if I change something in my .zprofile which causes an
exported environment variable to have a different value, then I'm
stuck with something like

    $ zsh -l
    $ killall i3; i3

to get i3 to see the new value. Usually it's not so important that i3
should see it, but commands which are started by i3 like 'xterm' (or
'urxvt') inherit from i3's environment. I usually want to change i3's
environment for their sake.

I was thinking of binding $mod+Ctrl+r to a command which does
something like "killall i3; i3". Is this the right way to proceed, and
if so, what exactly should the command look like? (I think it should
open a 'zsh -l', start i3 as a background process, disown it, and
exit, but I'm having some trouble getting this sequence to work)

Another option is to use some kind of IPC mechanism to tell i3 about
the new environment variables. I do this with 'screen' (script
attached) but I don't know how to do it with i3.

Of course, I could invoke each xterm as 'zsh -lc xterm', but I don't
like this option because of the extra latency it introduces.

Related is the problem of restarting Xorg, for instance if I give
myself a new group, then I need to start a new login shell in order
for processes to see the new group. This happens much more rarely.

I am interested to hear your thoughts.

Thank you,

Frederick




Other related posts: