How can I set an permanent environment variable per user independent from the used shell (bash, zsh and fish)?
- 2,033
- 2
- 18
- 21
-
not sure I understood, but if you want to set an environment variable for all shells, you can put it in `~/.profile` (for one user) or `/etc/profile` (for all users) – tbrugere Jun 24 '21 at 14:43
-
bash doesn't read ~/.profile, only /etc/profile. – Marcus Müller Jun 24 '21 at 14:46
-
then, you could, in `/etc/profile` add a `source $HOME/.custom-profile`, and use that (though it's a bit hacky) – tbrugere Jun 24 '21 at 14:47
-
2@MarcusMüller bash does read `.profile` when started as a login shell. The exception is only if _you_ or your sysadmin have created a `~/.bash_profile` file. Then, but only then, bash will skip `~/.profile` and read that one instead. – terdon Jun 24 '21 at 14:52
-
@terdon didn't see that in `man bash`! Good to know. – Marcus Müller Jun 24 '21 at 15:07
-
@MarcusMüller see the "INVOCATION" section in `man bash`, also reproduced in this question: [Why are interactive shells on OSX login shells by default?](https://unix.stackexchange.com/q/119627) – terdon Jun 24 '21 at 15:12
-
@terdon, indeed, there it is! – Marcus Müller Jun 24 '21 at 15:19
2 Answers
EDIT: according to What's the best distro/shell-agnostic way to set environment variables?, the best solution for this is ~/.pam_environment
EDIT: reverted to the hacky solution since ~/.profile is not read by all shells:
All shells source /etc/profile.
That means in /etc/profile, you could put a line like
. $HOME/.custom-profile
Then, you could add your variables to ~/.custom-profile for each user
- 966
- 6
- 16
-
You are just recreating the existing functionality. This is what `~/.profile` is for. If a shell reads `/etc/profile`, it will also read `~/.profile`. – terdon Jun 24 '21 at 15:09
-
yep, I was misguided by the comment telling that bash didn't read `~/.profile`, editing – tbrugere Jun 24 '21 at 16:10
-
The `zsh` shell does not read `~/.profile` by default, and neither does the `fish` shell. – Kusalananda Jun 24 '21 at 16:17
-
@terdon `zsh` only reads `/etc/profile` if it's started in `sh` or `ksh` compatibility mode. The `fish` shell does not to my knowledge read `/etc/profile`. – Kusalananda Jun 24 '21 at 16:19
-
-
Note that `source` is a built in utility in _some_ shells. The POSIX equivalent is `.` (dot). Fish has `source` too, but it's unclear whether any _other_ command in `/etc/profile` would understood by that shell. – Kusalananda Jun 24 '21 at 16:23
-
I changed `source` to `.`, though, do you have an example of shell that doesn't understand `source`? – tbrugere Jun 24 '21 at 16:26
-
@Kusalananda Seriously? Wow. My apologies, Nephanth, I stand corrected. – terdon Jun 24 '21 at 16:37
-
All shells read different per-user profile files (zsh: ~/.profile, bash: ~/.bash_profile, csh has only an rc file, and so on). So you'd have to change all of these potential candidates.
However, most shells at the very least fall back to reading ~/.profile (thanks @terdon for pointing this out!), so that's where you can put your exports.
Since "logging in" is usually done by a process having the ability to change its uid and gid (typically: a login manager runnning as root), it's up to these programs to define the environment for the spawned program (e.g. a shell).
But: there's more than one login manager (your GDM/lightdm/KDM/... visual login manager, getty, logind/loginct, ssh, getty...), and they read configuration from different files, so there's no consistent way there, either.
- 21,602
- 2
- 39
- 54