Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Environment variables are per-process, but inherited by child processes (not system wide). So when you start other programs you often set up env vars for them, or clear env vars that were used by your parent process to not inadvertantly perturb the child's behaviour.


Yes the proper way to do that is execve, not by changing global variables in your parent process. https://man7.org/linux/man-pages/man2/execve.2.html

Using setenv is mostly always a hack that relies on a bunch of assumptions that could easily change and be hard to debug.


Unless there is a fork exec family of syscalls are not child processes but the same process itself. Small detail but important because sometimes you really want a separate process altogether.


in that case you do not need setenv to pass values to the underlying process though. And if you are forking without immediately execv in a multithreaded program, setenv is the last of your problems.

edit: what's probably happening is that execve is four or five abstraction layers deeper (possibly in a third party dependency) than where the env variable need to be set without a clean way to pass the values through.


The likely scenarios I was thinking (setenv vs execve) would both be called in the child process after fork. But of course here we get to the fascinating world of fork interactions with threads, and you could even have one thread fork()ing while another thread is doing a setenv().


Regardless of whether it's a hack, my broader question is: is it common in Linux to manipulate environment variables on the fly for a process or program?

I primarily use Windows, both as an end-user and an amateur programmer. From my experience, most programs on Windows don’t do this. If parameters are needed, they’re usually passed as arguments, while environment variables are used for more permanent settings, like %PATH%.


PATH is a good example why steam does this: Steam is a program to launch a wide variety of other programs, which it doesn't fully control. Those programs (games) may do anything including launching further programs (utilities), so steam may set PATH so that the game finds those utilities.

It can also be a way to pass license information or other configuration settings.


Looks like the Steam team moved to control spawning and do execvpe.

I would like to see at least in-process environment modification discouraged. Rust is dealing with the issue by considering getenv unsafe when coming through C, but getting rid of the read side is much harder than the write side.


It is decently common enough in unix. You are correct with my windows stuff it is fairly rare to set env vars to change the launching process. In the unix world though I have seen the pattern a decent number of times. With windows programs usually you see the pattern (not always) if it is ported from a unix system. Windows likes its ini/registry/cli items to do configuration. It doesnt mean the pattern can not be used in windows, I personally just have not seen it as much with native win32 apps. If you fire up something like 'git bash' you can see entire bash functions bound to env variables.

I think it goes back to where windows came from. That environment space in DOS was not exactly huge (256 bytes at one point?). In unix it seems like it was much larger and expressive.


One thing to note about command line arguments on Linux is, any user can typically inspect `/proc/{pid}/cmdline` and get the full command line used to start the process. So if you pass secrets like API keys, passwords, etc, via an argument, they're visible to the rest of the system. However, if you put secrets into the environment of the child process, only the user that owns the child process can inspect `/proc/{pid}/environ`.


https://man7.org/linux/man-pages/man5/proc.5.html#DESCRIPTIO...

One can use `hidepid` parameter when mounting procfs to hide cmdlines.

I don't know why this is not implemented today by default in most distros. Probably history reasons.


My guess is it would break stuff like `ps x`, but ideally tools that use the procfs would gracefully degrade in cases like this?


Yes, the fact that the original article exists shows that it's common :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: