Are there names of environment variables that cannot be overwritten by the user/a call to setenv? As I understand from POSIX1.2008, any process may edit the environment block, but must avoid overwriting such vars as LANG etc.


The environment is a list of strings of the form var=value (by convention) that is passed as the 3rd argument to the execve() system call.

That list is put somewhere on the stack of the process when it starts to execute the new command just like for the list of arguments (another list of strings passed as the second argument to execve()).

In programs using the libc (most), an initialisation code called before the main() function is invoked, makes those environment strings available as the environ array.

The libc also provides with putenv and setenv functions that can modify (a copy of) that list that the program received. That maintained, modified copy will then be passed to the next command executed by the process or any of its children via the execvp()/execl()/system()/popen()... functions of the libc (which themselves end up calling the execve() system call).

Now while when you build up a list of strings that you pass manually to the execve() system call, you may pass strings like foo (without a = character) or =bar (with an empty variable name), setenv won't let you do that (setenv("", "bar", 1) is rejected).

setenv("a=b", "c") will also be rejected. So the strings that will be defined by setenv will always be of the format x=y where x may not be empty.

That's about the only restriction (also applied by putenv). Well those being NUL terminated strings, of course the NUL character cannot appear in the variable name or value.

setenv("*", "x", 1), or setenv("\n\n", "", 1) are all OK as far as setenv() or the kernel are concerned. Now, whether you're going to be able to do anything useful with those is another matter.

| improve this answer | |

No, there are no restrictions on which environment variables can be changed by a process. However, keep in mind that each process has its own copy of the inherited environment, and a process cannot change any environment variable in any other process. The setenv call can only modify the environment within the calling process.

| improve this answer | |
  • 1
    Can change the future children's env, right? – Deer Hunter Jun 16 '14 at 2:44
  • 1
    Yes, a process can completely control the environment block of its children (but only the environment at the moment of process launch; the parent cannot change environment variables in its children after the children have started). – Greg Hewgill Jun 16 '14 at 2:54
  • Permission wise, a process can change the environment variables of any process it has ptrace permissions for. – Timothy Baldwin Jun 26 '19 at 22:38

I think it depends completely on the shell you're running.

In Bash UID is one BASH_VERSINFO is another according to the man page.

On the other hand in csh according to the manual Environment variables cannot be made read-only.

| improve this answer | |
export MYENV=value
readonly MYENV
| improve this answer | |
  • 2
    An explanation of what this does and (if applicable) what shells support this would be nice. – Mat Jun 16 '14 at 7:50
  • 3
    This does not protect the environment variable, it is just an internal restriction that is entirely local to your shell. – Chris Down Jun 16 '14 at 8:01
  • for a child shell, I think we can keep track of such readonly variables and issue a command on these to make them readonly there too, may work thx – Aquarius Power Mar 20 '15 at 20:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.