4 ms·
>"Wow, I really enjoyed writing this… …and I hope it wasn’t a boring read." No, it was very interesting actually! An excellent deep-dive into the murky area o
by peter_d_sherman 1y ago
>"Wow, I really enjoyed writing this…
…and I hope it wasn’t a boring read."
No, it was very interesting actually!
An excellent deep-dive into the murky area of Unix/Linux environment variables, how they are set, how they are passed, what's really going on behind the scenes.
Basically a must-read for any present or future OS designer...
Observation (if I might!) -- environment variables are to programs (especially chains of programs, parent processes, sub processes and sub-sub processes, etc.) what parameters are to functions -- and/or what command-line parameters are... they're sort of like global variables that get passed around a lot...
They also can influence program behavior -- and thus the determinism of a program -- and thus the determinism of a chain of programs...
Phrased another way -- software that works on one developer's machine might not work on another developer's machine and/or in a production environment because one crucial environment variable was either set or not set, or set to the wrong value...
(NixOS seems to understand this pretty well... that "hermetically sealing" or closing or "performing a closure around" (that's probably slightly the wrong language/terminology in "Nix-speak" but bear with me!) a software environment, including the environment variables is the way to create deterministic software builds that run on any machine... but here I'm digressing...)
But my main point: I complete agree with the article's author -- environment variables are a legacy mess!
Although, if we think about it, environment variables (if we broaden the definition) are a sub-pattern of anything that affects the state of an individual machine or runtime environment -- in other words, things such as the Windows Registry, at least the global aspects of it -- are also in the same category.
Future OS's, when they offer environments for programs or chains of programs to run -- should be completely containerized -- that is, the view of the system -- what data/settings/environment variables/registry variables/files/syscalls/global variables it has access to -- should be completely determinable by the user, completely logabble, completely transparent, and completely able to be compared, one environment to another.
In this way, software that either a) fails to work at all b) works in a non-deterministic way -- can be more easily debugged/diagnosed/fixed (I'm looking at you, future AI's that will assist humans in doing this!) -- then if all of that information is in various different places, broken, and/or opaque...
To reiterate:
>"Wow, I really enjoyed writing this…
…and I hope it wasn’t a boring read."
No, I really enjoyed reading it(!), it's a brilliant article, and thank you for writing it! :-)
Upvoted and favorited!
- chriswarbo 1y ago> environment variables are to programs (especially chains of programs, parent processes, sub processes and sub-sub processes, etc.) what parameters are to functions -- and/or what command-line parameters are... they're sort of like global variables that get passed around a lot... They're not globals, since they're copied into sub-processes; so mutation doesn't propagate upwards. My own opinion is that environment variables are dynamically scoped keyword arguments http://www.chriswarbo.net/blog/2021-04-08-env_vars.html http://www.chriswarbo.net/blog/2021-04-08-env_vars.html
- peter_d_sherman 1y ago>They're not globals, since they're copied into sub-processes; so mutation doesn't propagate upwards. If we broaden our thinking to look at a computer process as a mathematical function, i.e., if we think about a computer process as y = f(x) Where y is the behavior of the function (what final state it results in / resolves to), f is the process itself, and x is the parameter or list of parameters that are passed to f, then if that process reads and subsequently alters its behavior in relation to any environment variable, then we should no longer think of that function as merely y = f(x), but as y = f(x, z) where Z is the set of environment variables that are consumed by, and subsequently alter the behavior of f, resulting in a different y. Now not all processes read environment variables and alter their behaviors because of an environment variable being set. That is true. Those processes remain as y = f(x). But if a process does read and does act on an environment variable (usually without the end-users' knowledge, because how many users keep track of which programs read/act on -- which environment variables?), then then this the same as passing extra parameters -- y = f(x, z) -- to the function! (Sub-observation: A future OS would have an API call to granularly read a single named environment variable at a time (not the entire block of them at once!), and use of this call could be logged and sorted by program, and there would be a user-settable control to granularly determine which environment variables could be read by which programs/processes...) >They're not globals, since they're copied into sub-processes; so mutation doesn't propagate upwards. Mutation or non-mutation upwards -- is not the issue. The issue is: If users run program f and they pass it various command line parameters x, and they want y, then if environment variables are present and if they alter the behavior of that program, then what the users are really getting is y = f(x, z), which may not be the behavior/result they want, because z influences the behavior, and is passed in a not-really-all-that-transparent manner (most people usually don't check, log or modify environment variables nor account for them in the determinism of their programs -- unless something is broken...) Phrased another way -- a future OS would have some way of logging everything, all state information (including environment variables which includes registry settings) -- that go into any given program. Now maybe environment variables aren't "globals" in the strictest definition... But let's see... In most modern operating systems as of 2025, environment variables can easily be read by most programs, functions/procedures/methods inside of those programs, sub-functions/sub-procedures/sub-methods of those programs, etc., etc., etc. Once they can be read... they can become the state of one or more variables in that program its functions, sub-functions, etc. And once it can become the state of those one or more internal variables, the program can alter its behavior / result -- based on them. Global variables -- can do the same exact same thing to a program. So I'll leave it as a linguistic/semantic debate to future readers, mathematicians, programmers and OS designers -- as to whether or not environment variables (and related globally readable objects such as the Windows Registry) are global variables... (You are very much correct about environment variables -- if they are mutated (aka written to/overwritten) by by a sub-process, then that mutation doesn't typically propapagate upwards the parent/creator process chain -- but perhaps in the context of my discussion, I am interested/concerned about -- the global readability/accessibility of environment variables... But you are very much correct in your statement!) I think the key point that I am trying to make is that more transparency/insight/logging could always be had as to where exactly programs get ALL of their inputs from (this includes environment variables, this includes API calls which may differ machine to machine, etc., etc.), and what average end users are made aware of...