This is something to watch out for especially if you're switching from screen to tmux.
When you start a screen session, it will always copy the environment from your shell. When you start a second screen session, it will inherit a possibly different environment.
But tmux, on the other hand, spawns a tmux server when you first start a session. It'll copy the environment from your shell. However, from that point onwards, new sessions will use the environment from the server and will not copy the environment from your shell.
I like screen's behavior more. A frequent use case is to start a long-running command as a sort of ad-hoc background job. That's really easy with screen (just run screen and run your command, it will always use the parent shell's environment) but relatively easy to screw up with the environment when done with tmux. It kind of works only if you don't have a tmux server already running.
I have tried on multiple occasions to migrate to tmux (because gestures vaguely "it's the future", screen's codebase is ancient and can still connect directly to a serial port etc), but I just don't like the primitives that tmux gives you ((servers,) sessions, windows, panes).
I use a nested setup with screen where each level of nesting has a different escape key, this works really well when I want an inner screen to be on a different machine.
I haven't figured out a way to get this to work well with tmux, because the local tmux server doesn't know about the remote tmux sessions. Whereas with screen, screen doesn't need to know or care about that.
(edit: I use shell aliases, I don't type out the '-e^Oo' etc every time)
I'm looking to skip tmux and migrate straight from screen to zellij instead, since it's also modern. I don't have many problems with screen, but lack of full color support (for vim) and wanting more terminal control codes (hyperlinks, text underlines, sixel, etc) speak in favour of using a more modern solution.
I want to love zellij but can't get over how it binds its own actions to practically every key (vs screen/tmux which take just one, the prefix). Do people who use it not use any programs that use control or alt keys?
I also trying to come to terms with this, mostly need to design new custom key settings.
Zellij has Lock interface, default Ctrl+G, which you can use and in that mode it only takes that one key, but it's a bit different from how screen works.
I recommend using tmux mode and adding its keybind to locked mode, that way you get the same key interactions as tmux itself. Sadly, zellij doesn't offer the same options for which key that will be (in screen and tmux I like using C-] cause it's usually unused, but you can't use that one in zellij)
Thanks for pointing out zellij [0]. I wasn't aware of it and am really glad to have read about it.
It's odd. A couple of days ago I watched Tristam Oaten's No Boilerplate video "Oxidise Your Life" [1] and it left me thinking about how Rust is moving some programmers to rewrite tools in Rust and, while at it, adding modern features. It's nice to see that.
I was quite satisfied with tmux but this issue (and one other) really drove me to seek an alternative like zellij so bad, but just couldn't settle on it for one reason or another. Instead I ultimately found refuge in kitty term which as a whole emulator is an overkill, but it's a great replacement and mostly as customizable. It does a good job with windowing - I particularly like the xmonad style window size switching. But there are still some parts of the tmux ecosystem I miss, like tmuxinator and the extracto plugin but otherwise most of my needs have been met, and the speed is a welcome bonus. So, can definitely recommend kitty as a good tmux alternative.
Wait until you find out how many people in the 21st century are still iterating on the idea of the wheel itself. Imagine if nobody tried reinventing wheels since they were first introduced and you have your answer.
i do exactly that with tmux. the primary difference is that don't nest tmux locally, but each tmux session is on a different computer, so they all just need their local config where the escape key is specific to the computer.
why does the local tmux server need to know about the remote tmux session?
C-b s gets me graphical(via rofi + some scripting) searchable list of windows, in rare cases where I'd need tens of them.
But it took me a while to make tmux keybindings that are fast & convenient, screen defaults (aside from C-a that collides with bash/emacs) on keybindings are way better.
> I haven't figured out a way to get this to work well with tmux, because the local tmux server doesn't know about the remote tmux sessions. Whereas with screen, screen doesn't need to know or care about that.
I'm missing something here. Why does tmux need to know or care?
local computer with screen
\
\ ssh/mosh to remote A, run screen
\
\ ssh/mosh to remote B, run screen
If each uses the same prefix (the default is C-a for screen, C-b for tmux) then you have to send it multiple times to send a command to the screen sessions on either of the remote systems. If you give each a unique prefix then you can send the prefix once and it goes directly to the desired screen session.
Easier to give each system its own prefix that's constant regardless of depth, though, than trying to remember "Did I connect to A first or B first today?". Or, better in my experience, don't nest them. It's a pain however you choose to deal with the prefix problem.
Instead of keeping N terminals open for N projects, I usually keep only one open and put each project in a screen session, then wrap them all in a “meta” session.
I started using this pattern before I moved to macos, but now that I’m usually on a mac, it helps because I still haven’t gotten used to macos window / desktop management. Managing one terminal is easier than a half dozen.
I do that except with terminal emulator sessions. One window with few tabs per virtual desktop, as I rarely need to have more than 2-3 projects open at the time it works fine.
But... isn't tmux sessions exactly what you'd need for that? One session per project, then just connect to servers from within tmux windows
There is even switch-tree (default C-b w) that will show each session with every sub-window in it, and even preview window below that showing each terminal (refreshable via space)
The problem here is the reliance upon environment variables being set by parent processes. That's always felt weird to me.
I think tmux's choice is actually the sane one. You create the server once, then there's no more question about what environment variables are going to be established in the future.
When you create a new tmux window, you should know if there's already a server spawned.
> ...the reliance upon environment variables being set by parent processes. That's always felt weird to me.
I don't really agree. When I start a program in a shell, I expect it to inherit the environment of that shell. That's just how things have always worked, modulo some special cases (sudo, running a new instance of the shell in login mode, whatever).
I personally don't think that's weird, but even if I did, what I care most about software behavior is predictability. Software should do what is expected and common, and if it does not, it should have a very good reason, and should find a way to make that obvious to the user every time it does it.
This is just bad UX on tmux's part.
> When you create a new tmux window, you should know if there's already a server spawned.
What? Why? I use screen on and off, not super often. When I start a screen instance, I don't always know or care if I have another instance running somewhere. And yes, because screen follows what I'd consider a more predictable model here, I end up with the environment variables I expect.
I think whenever we attack a UX problem by saying "the user should know X", we've already lost. You can't assume that you know how the user is going to use your software, or what their state of mind will be when starting it. That's just silly.
I don't know about other people - but I spend greater than 99.9% of my time inside a tmux session. It is my windowing environment. I was reading the original post and just kept furrowing my brows wondering "Under what possible scenario could any of this possibly be a problem?"
It's kind of interesting reading through the threads here and seeing how people don't spend their time inside tmux all the time but instead "start an instance on demand" - which I've never done but I guess works for some people's workflow?
I'm genuinely crippled trying to use a terminal without tmux after having used it for so long - don't have the faintest clue how to copy/paste/search/organize windows without it.
Something like yakuake does tabbing, splitting, and is scriptable via dbus commands. There is no strong need to learn tmux key bindings to use locally.
I was a casual tmux user until I got stuck in a portable trailer in Dubai working for DEWA on their grid, and they had us using a janky remote terminal Remote Desktop setup that didn't have any form of mouse pass through to the linux terminals we were doing work on. So - copy/paste were not possible which made work a pain. I gave them a DVD (!) containing the various ncurses/libevent/tmux code - and voila - I finally had a working environment.
I spent 2+ months in that trailer for 6-8 hours/day - and tmux became so embedded in my finger DNA, I never looked back.
I routinely bounce between WSL, Linux, and MacOS and never have to remember any of the keyboard shortcuts for the terminal programs, or whether it's been installed, and my fingers never leave the keyboard - and I can almost always outperform someone trying to select/copy with a mouse/touch pad. My .tmux.conf is the only thing I pull along with me.
Also - just thinking about it - tmux is more than just a windowing environment - it also does project management. I have a workflow where every new project/issue/incident gets its own named window - and then I break up that window into a set of 4-8 panes based on systems (or sets of systems) I'll be working on. They all share the same bash_history. As I get hit with interrupts, I bounce between sessions and when I come back - my whole thought process/work history is back in that named window with panes. It's not unusual for me to have 45-50 open panes at a time - all perfectly organized by project/named window. With the resurrect plugin, and intelligent use of my bash config - I can (and do) pull everything (scroll back history, bash history, etc..) onto another system if needed (great if you need to recreate your work history and you no longer have access to the original terminal environment).
As I close off/complete projects, I terminate the window - but the bash history is kept clean in ~/.tmux/bash_history/window_name in case I ever need to start working on it again (recreating the window with the same name pulls back in the bash history)
Introspecting here a little, this honestly is probably more a function of me spending 40+ hours in a terminal environment than anything a rationale casual user would ever want to do.
Sure, if this is a big part of your workflow then that makes sense. Personally, I end up running 1-2 workstation machines with GUIs that I sometimes remote out from, but ~never into (apart from sometimes retrieving files from the desktop when I'm away).
You are not using tmux for what it's designed to be used. It's not for running long-running processes, even though you might use it this way (you could also use eg. Photoshop to run long-running processes, after all, it has an embedded JavaScript interpreter with some extra functionality that might allow you to do that).
tmux serves the same purpose as DE, except w/o the whole windowing system etc. It's to allow you to switch between multiple applications which require terminal for interaction.
I spend close to 100% of my time at work inside tmux, and I never needed to answer a question "where do the process variables come from?" -- it's irrelevant in the same way how you don't ask where does Gnome get its environment variables from. You simply don't rely on environmental variables when running tmux / don't care about them.
> When I start a program in a shell, I expect it to inherit the environment of that shell.
That's exactly how tmux works. You start a server, it inherits the environment of the current shell. You create a new session in that server, it inherits the environment of the server.
I don't understand how forcing tmux to re-load the current local environment for each new shell is saner behavior. One natural consequence would be that new panes in existing sessions are also created with the new env vars, which is obviously undesirable.
>> When I start a program in a shell, I expect it to inherit the environment of that shell.
> That's exactly how tmux works. You start a server, it inherits the environment of the current shell. You create a new session in that server, it inherits the environment of the server.
Whether that makes sense depends on if your mental model has starting a server and connecting to a server to create a new shell as distinct actions, as opposed to a singular action of connecting to a conceptually always-present persistent environment and starting a shell there. Admittedly tmux’s interface is mostly organized along the former lines, but given I prefer `tmux new -A`, my own model seems to follow the latter.
I disagree. tmux default behaviour suits my workflow much better. It's complex enough problem that there is no perfect default so complaining this or that doesn't fit you when you can just change it so it does is pointless.
It would make sense if there were 2 commands, tmux-server for starting the server and tmux-client for starting the client. The client would then support options to connect to an existing server or spawn a new one.
I'm a big fan of abstracting away details of little importance. But if I risk using an old server with stale values in its environment, I prefer that to be made explicit and not abstracted away.
How is that "predictable"? The standard behavior for more or less everything is that, by default, when you run a process, it will get its environment from the parent process. Getting its environment from a magical hidden server process that a casual user may not even know about is the opposite of "predictable".
it's not magical or hidden. every invocation of tmux is a call to a running tmux server. the only exception is when no server is running, in which case a new one is started.
i have tmux running all the time. started once when i connect to a server for the first time, it keeps running until the server is rebooted. i have tmux sessions that go back years.
the only time the environment is causing me trouble is when a new ssh connection is forwarding an ssh agent, which doesn't get transferred into the tmux session when i attach. but screen would not help here either. if you connect to an existing screen session it has the same problem. we really want a way to adjust the environment for specific variables on attach.
If you run an SSH client process to connect to an SSH server, the resulting SSH session will not inherit the environment from the parent process of the client by default. Although not the same, connecting to a tmux server is more similar to that than starting a regular child shell.
Environment variables get immutably set when you run the process, that screen would re-evaluate them when launching another window is bizarre. I'd expect the opposite case to be a problem, that when using screen you'd export environment variables by accident more often.
FWIW, as someone who uses screen, to me the opposite is "bizarre"? ;P I am at a shell, and I run "bash". This opens a new shell, but inherits both the environment and the working directory from my shell. Or maybe I run "ls": same thing. Now I run "screen bash" or "screen ls"... this should intuitively run the command as if I had just run the command but do so in a new "window". It would be absolutely ridiculous if "screen ls" didn't inherit the environment from the current shell.
We had this happen at my company. I had set some new memory settings in a JAVA_OPTS environment variable due to heap issues. The DBA kept a tmux server running and would periodically restart our app when they needed to do work on those tables it interacted with during maintenance windows.
The heap issues kept occurring even though I triple checked the ENV variables. However, ps -ef showed the old values!
Once I figured out he was using tmux the issue was resolved by closing out all sessions and starting new ones.
I've gotten comfortable with the way tmux works, but the complaints raise a valid point. Its default behavior of prioritizing server environment over session environment is probably the wrong one. Maybe those who don't see this are conflating windows and sessions (I can clearly see this in the comments). Different sessions imply radically different projects, paradigms, contexts. Whereas different windows in a session imply different perspectives, views, within a shared paradigm.
Intuitively, it makes sense to be able to start a tmux session after setting up some global (i.e. session wide) environment variables, so that all new windows spawned in that session inherit them. Once you've specified the database or various urls, you don't want to have to source some environment file each time you spawn a window. The session should just already know all this.
Inheriting some super global variables (i.e. server wide, machine wide) by default (as opposed to explicitly setting a flag) implies that a shared environment across sessions is more useful than a shared environment across windows within the same session. It's a matter of opinion, taste, or maybe of UX data points, but I suspect that the latter would be favored if there ever was a survey.
In 10+ years, outside of perhaps experimenting with the feature for a few hours to see how it works - I've never created a second session in tmux. I routinely will have 20-25 windows and another 4-6 subpanes inside those windows though.
I'm wondering if sessions were more relevant before we all had 30+" monitors on our desk, and panes were less useful. Or perhaps some people have, as you noted, more well defined work/project paradigms that they can associate with a session.
With that said - in my day job, we have a really well engineered set of tooling that lets us manage our certificates, ssh keys, and orchestraor/security engine/service discovery tokens - but I'm managing and updating dozens of environments/configs - honestly the environment that I opened even a single pane (inside a window) might shift several times over 5-10 minutes into entirely different clusters - what that pane started with is mostly irrelevant - (and clearly the windows/session and "Tmux Server" environment that I started with is so irrelevant as to be meaningless).
About the only global original configurations that I care about and want to carry into my work are bound to my client (/etc/hosts, /etc/resolv.conf, interface, VPN, etc...)
The one thing that I've gotten out of this thread is that I probably should be more empathic to other people's workflow - not everyone has the same datacenter/cluster/server environments that I do - and instead of having tooling to manage their environment, they might just rely on what it was when they were launching a "new tmux session at that point in time" (a concept I had never considered until today).
I agree with you. I suspect it is around understanding that tmux is a server, which you start and connect to.
Its my daily driver, but that means when I am in bare zsh, without tmux, it usually doesn't "work" for me. So, I can understand if someone is just spinning up tmux occasionally (to keep some long running program from stopping) that it can be a bit jarring. In some senses, the simpler 'screen' might actually be a better fit for that.
But yea, using tmux every day for years you become very thankful of how it operates, keeps variables isolated, you tend to work in one session per project (and it's great for not mixing them up).
But yea, it wouldn't be great if you are working away on something, then half way through just "start a session".
Tmux isn't going to do what the op is trying to do I suspect.
I'm a big tmux fan, it is awesome (in case that wasn't clear)
Interesting that you do one session per project - I've experimented occasionally with that, but I ended up in the one window per project, and then break up the work in to 4-8 panes (more or less). Every window gets a name (my new window shortcut requires it) so it's relatively straightforward (for me) to find the project context, particularly as the bash_history is named after the window, and shared between panes (so you can pull the entire work history for a project based on its name).
OP here. We have some make tasks that set up a local dev environment and rely on environment variables to control a few things. We ran into an issue where if someone started another tmux session and then ran the make task to start the dev environment the env vars wouldn't be set correctly causing some confusing behavior.
I wouldn't rely on env variables. I'd make a script that goes somewhat like
script envname command
then just loads .env.envname before executing.
For k8s work I just put some relevant variables in PS1 so it is always visible "where I am", with prompt looking like this for say "dev" env:
[08:15:57] ^ [~]
k8s:dev -> ᛯ
As for tmux behaviour, it's honestly entirely understandable. tmux have no way of knowing the intent of the user; some people might want "clean" session with defaults of what server is running, other might want some env variables copied.
I don't have that problem because I just have session being created in my WM autostart, and I just use that one session 99.99% of the time. And creating new ones usually is from tmux, not from some random shell window elsewhere
Yeah that makes sense. To me it felt unintuitive that environment was global and only copied on server start, with a few exceptions, and not session start but that was likely just a failure in my mental model of how tmux worked.
I think it's about the stuff that needs to be shared. Like variables for X11 or ssh agent.
If you start server off your graphic session then any new tmux session will get those variables and your ssh agent or graphical app will "just work".
Reading from current one by default might fuck something up if you say have some automation that starts stuff in tmux
There isn't really good way to handle it by default that would make everyone happy, screen had similar "problems".
I just have
tmux new-session -d -s main
in my .Xsessionrc so the main session gets both SSH_AGENT stuff (I use gnupg as agent, for smartcard support) and proper DISPLAY, then just use alias to use that main session
Could you encapsulate the config to a file within your build step and set the env vars from that? Like a “remember to source <envfile> before make dev” or better, if the env isn’t set in make properly (flag), have make source it.
Environment vars are great with defaults for configuring codebases. They are designed for runtime. Build time flags can read the current environment but if your build pipeline requires custom variables you need a “dictionary” of sensible defaults that will spin up a local environment so that onboarding is as easy as git clone && make dev.
I wonder if it's because of export. If one puts an env var into a command alone then it should be OK. For example, `MY_VAR=1 my-commmand.sh` should leave env vars unchanged for everything else.
Yes that should work. In our case we have a few different windows/panes that all want the same environment so it made sense to reach for export as a way to ensure the environment was set but then ran into this quirk of tmux
You can use the include syntax for Makefiles in order to include your environment variables.
Alternately, set those vars in your shell RC and it'll work too when the shell is spawned.
IME it's stabler to kick off automation or build processes from a clean slate anyways, clearing the environment and setting specific values as required from a file.
I would have expected that sessions are completely independent from each other, and don't magically inherit some (but not others) environment variables from when the first session was created. (Especially considering the first session might not even exist anymore!)
That said, I can understand why it would work this way for simplicity, if all sessions are hosted inside the same process.
Luckily for me, I never use more than one session at a time, so this doesn't affect me.
His solution of using `-L` to create a new named socket for each server does not seem cumbersome to me. I usually run `tmux attach-session` only once per day, so an additional argument would not be a major cognitive load. And I'd imagine most people use shell aliases for that sort of thing anyways (I probably should).
yea i always do `tmux new -s dev` to start one and `tmux attach -t dev` to attach
correct me if im wrong but it seems like i can just do `tmux new -L dev` and `tmux attach -L dev` which is actually better than my old muscle memory. its a win-win for me
edit: actually jk it doesnt work.
meh who cares i always put my env vars in ~/.profile its weird how OP doesnt mention that at all
I think the biggest problem I encounter when trying something else than tmux is copy-pasting without having to use the mouse. How does the "local terminal guis" you suggest as alternatives handle that?
Not quite. I don't think my setup is very special, so, I describe it in more detail:
My company provides me with the laptop, VPN connection to the office network, which, in turn, connects to our (tiny) datacenter, where actual work happens (i.e. compilation, CI, testing, all happen there).
Sometimes I work from the office, other times from home.
The datacenter has several "jump" servers having distinct roles, there is a server that lets you connect to our OpenStack cluster, another has some resources to run a bunch of unrelated VMs in KVM, yet another one is the storage for all kinds of artifacts, s.a. Linux packages, Linux distro images, Docker images for development and testing, and then there's CI cluster.
So, my typical setup is like this: I have an ansi-term buffer per jump server. The jump servers are running my tmux session. So, every time I have to move my laptop to a different network (eg. going home from office), I reconnect to the jump servers and to the tmux session they were running so that I can pick up from where I left off before disconnecting from office VPN.
If TRAMP could have a persistent session, maybe, I'd not use tmux (I don't like that I have different commands for managing buffer appearance and clipboard). On the other hand, tmux is more universally used (at least in my company), so that sometimes I can simply ask a colleague to connect to my session, if they need to investigate some strange situation (only a handful of people are using Emacs, but almost everyone would be able to use tmux at where I work).
Might be worth looking into detached.el for persistent sessions? Tbh I haven’t set it up properly myself, but I did watch the talk from EmacsConf and I plan to look into it further.
Thanks for this! Unlike a stereotypical Emacs user, I haven't touched my configuration in a few years. Guess, I'll need to do some cleanup / research in the near future.
I switched from screen to tmux because it was often impossible to detach a remotely attached screen (for example when your ssh connection dropped and you wanted to reattach to screen).
Would `screen -d -R` & al not work? From `man screen`:
-d|-D [pid.tty.host]
does not start screen, but detaches the elsewhere running screen session. It has the same effect as typing "C-a d" from screen's controlling terminal. -D is the equivalent to the power
detach key. If no session can be detached, this option is ignored. In combination with the -r/-R option more powerful effects can be achieved:
-d -r Reattach a session and if necessary detach it first.
-d -R Reattach a session and if necessary detach or even create it first.
-d -RR Reattach a session and if necessary detach or create it. Use the first session if more than one session is available.
-D -r Reattach a session. If necessary detach and logout remotely first.
-D -R Attach here and now. In detail this means: If a session is running, then reattach. If necessary detach and logout remotely first. If it was not running create it and notify the user.
This is the author's favorite.
-D -RR Attach here and now. Whatever that means, just do it.
Note: It is always a good idea to check the status of your sessions by means of "screen -list".
Believe me I tried all combinations, lowercase and uppercase, it would just freeze, as if it was trying to get my session back, but it wouldn't do anything. It happened often, and I would lose my sessions, so I learnt to use tmux, and that's what I've been using for ten years.
Yeah... I kind of vaguely remember having an issue with this sort of thing 20 years ago, but I don't remember if I even knew about force detach at the time. I definitely haven't experienced a screen session I couldn't detach--and I use screen a LOT--in at least 10 years... probably 15.
May be I misunderstood the article but the tmux behavior I see is slightly different.
The env vars from the shell where most recent attach happens are inherited when creating a new pane or window. This is the case even when multiple terminals are attached to the same session.
This seems similar to VSCode and it’s shell sessions. You need to restart VSCode to pick up new environment variables rather than just open a new shell. But at least you have a UI in your face to sort of remind you. With tmux server maybe it is less obvious that this will happen.
At least to me, it seemed most intuitive to not have a global server environment and always copy the environment when starting a new session not just on server start and have the existing behavior when attaching to a session.
Somewhat related: I had no end of trouble trying to configure my locale on a raspberry pi. Tried everything I could find on the internet, still had inexplicable errors with environment variables not being set or being set differently than I had just set them.
It's because my ssh session was bringing variables from my laptop onto the pi:
I think it's undocumented but you're supposed to be able to have update-environment set to '*' so it always uses the parent shell's environment variables when creating a new session.
I have a very quirky setup with tmux and rely on this feature, but it's broken IIRC and add important variables to update-environment manually.
This part at the end is something I use a lot to re-attach to a running session:
> to re-attach to the second session you’ll need to do tmux -L other attach -t second.
I have tmux running on a machine in my closet that I ssh to from a couple of different laptops. I name each session, and then always connect to the same session when I ssh into the closet machine.
tmux a -d -t session-name
The -d makes the sessions resize to match the current scrren size which is useful for me because I use different screen resolutions on both laptops.
-d causes the other attached clients to become detached from the session. tmux, like screen, limits the size of the rendered window to the smallest presently connected. It happens that it forces a resize to match your current screen size, but that's not its primary purpose.
If you want to retain complicated window setups without running multiple sessions concurrently I really like tmuxinator [1]. It lets you declare everything about the session in a config file, and restart the session based only on the file.
It seems like the behavior would cause problems in the following workflow:
- create first session (launch server)
- detach
- set environmental variables
- create second session
But I don't understand why you would want to follow this workflow in practice.
When using tmux, all my work on that machine is done within tmux sessions, and I expect them to be sandboxed relative to each other. If I want to set an variable that's relevant to a session, I do it from within the session, not outside.
From a user perspective, it can look like indeterminate or unexpected behavior - the set of environment variables available within the tmux session depends on the state of the world at the time the tmux server was started, as opposed to when the session was started. The tmux server may start when the session starts, or it may have started much earlier - as a user, unless you're aware of this behavior and paying attention, you won't know.
Other posters are right that the "correct" workflow is to set all your environment variables explicitly within the session before launching whatever process you're running, but on an ad-hoc basis, I've often found myself logged into a server and thinking "this may take a long time, I should run this in a tmux session," and this kind of behavior would have (and probably has) bitten me in that case.
I've found for myself that it better start tmux/screen session on server up on login and don't spend time thinking on per case basis. So 95% on ssh sessions I use run tmux inside and usually the first command after ssh login is tmux attach. 5% cases are exception when no tmux/screen available or cannot copy my own tmux.conf
OP here. Apologies for not providing the real world example that triggered the behavior but here's some more background: We have some make tasks that set up a local dev environment and rely on environment variables to control a few things. We ran into an issue where if someone started another tmux session and then ran the make task to start the dev environment the env vars wouldn't be set correctly causing some confusing behavior.
Ultimately we decided to use a named tmux socket to ensure the environment variables were picked up correctly when set via the make task but you can also use `set-environment` as well if the ergonomics hit of having to use the named socket each time is too much. It's nice that tmux provides a few work arounds but I thought the original behavior was not intuitive.
If you thought you were reloading the dev environment database, and found out you just reloaded your production database, you would be surprised too. And you would probably wonder why after setting the dev variables, the tmux shell didn't have them.
It's one of those rare gotchas that will bite someone in the ass. And it will hurt. And when it does, you'll swear like a mother f'er.
When you start a screen session, it will always copy the environment from your shell. When you start a second screen session, it will inherit a possibly different environment.
But tmux, on the other hand, spawns a tmux server when you first start a session. It'll copy the environment from your shell. However, from that point onwards, new sessions will use the environment from the server and will not copy the environment from your shell.
I like screen's behavior more. A frequent use case is to start a long-running command as a sort of ad-hoc background job. That's really easy with screen (just run screen and run your command, it will always use the parent shell's environment) but relatively easy to screw up with the environment when done with tmux. It kind of works only if you don't have a tmux server already running.