0

How can I set an permanent environment variable per user independent from the used shell (bash, zsh and fish)?

BuZZ-dEE
  • 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 Answers2

1

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

tbrugere
  • 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
  • ok reverting to previous answer – tbrugere Jun 24 '21 at 16:20
  • 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
  • @terdon No problem, I was unaware too – tbrugere Jun 24 '21 at 16:39
0

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.

Marcus Müller
  • 21,602
  • 2
  • 39
  • 54