19

I'm using zsh and gdm to run gnome. Some time ago I discovered that variables are not set correctly. For example LANG/LC_ALL are incorrect ("" instead of en_GB.UTF-8).

I split the .zshrc into .zshrc and .profile. In the latter I set the environment variables, but how can I set the variables before the session starts? I tried a few choices (.xinitrc, .xsessionrc) but none seemed to work.

Edit To clarify - I used .profile and manually sourced it in .zshrc. It does not change question anyway.

simon
  • 1,498
  • 1
  • 11
  • 15
Maciej Piechotka
  • 16,578
  • 11
  • 57
  • 93
  • Is your `.profile` not loaded at all, or is something else overwriting the locale variables? (Try setting some other variable like `export MACIEJ_PROFILE=yes` to make sure. `set -x` in `.profile` may be a good way to check what is being executed in and after `.profile`, if it's read at all.) There is no point in sourcing `.profile` from `.zshrc`. – Gilles 'SO- stop being evil' Dec 07 '10 at 23:40
  • Is this a problem in terminal windows or elsewhere? Do you get your desired locale settings when you run `ssh localhost zsh`? What about `ssh localhost bash`? If bash is ok but not zsh, maybe you put something in `/etc/zshenv` or `~/.zshenv` (which is pretty much always a bad idea). – Gilles 'SO- stop being evil' Dec 08 '10 at 00:02
  • No the shell is working OK (before and after split). The problem is that `gnome-session` does not have this variebles set. – Maciej Piechotka Dec 08 '10 at 11:39

2 Answers2

31

The simple way is to invent a time machine, visit the various people who devised shell startup files and tell them to cleanly distinguish between three things:

  • session setup, e.g. environment variables;
  • session launching, i.e., e.g. starting a command-line shell or a window manager or running startx;
  • shell initialization, e.g. aliases, prompt, key bindings.

It's not too hard to get session vs. shell right in a portable way: login-time initialization goes into .profile (or .zprofile, or .login), shell initialization goes in .bashrc or .zshrc. I've previously written about .bash_profile, zsh vs. other shells, more about portability (mostly about bash), more about who reads .profile.

A remaining problem is distinguishing between session setup and session launching. In most cases, ~/.profile is executed when you log in and can double as both, but there are exceptions:

  • If your login shell is (t)csh or zsh, ~/.login and ~/.zprofile is sourced instead of ~/.profile. Ditto for bash and ~/.bash_profile, but this is easily solved by sourcing ~/.profile from ~/.bash_profile.
  • If you log in under a display manager (xdm, gdm, kdm, …), whether your ~/.profile is read depends on the version of the program, on your distribution (Linux or otherwise), and on what session type you choose.
    • If you count on the display manager to start a session for you, your .profile must set environment variables but not start a session (e.g. a window manager).
    • The traditional configuration file for X sessions is ~/.xsession, doing both session setup and session launching. So the file can be essentially . ~/.xsession; . ~/.xinitrc. Some distributions source ~/.profile before ~/.xsession. Modern distributions only source ~/.xsession when you select a “custom” session from the display manager, and such a session is not always available.
    • Your session manager may have its own way of setting environment variables. (That's an optional part of your desktop environment, chosen by you through a configuration file or by selecting a session type when logging in; don't confuse it with the session startup scripts provided by the display manager, which are executed under your user but chosen on a system-wide basis. Yes, it's a mess.)

In summary, ~/.profile is the right place for environment variables. If it's not read, try sourcing it from ~/.xsession (and start your X programs from there), or look for a system-specific method (which may depend on your distribution, display manager if any, session type if display manager, and desktop environment or session manager).

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • `.xsession` was the file I was looking for. – Maciej Piechotka Dec 08 '10 at 11:45
  • 1
    I agree strongly with everything except your summary. I don't think you established this point. If your `.profile` sources `.bashrc` or similar, then you can reliably set environment variables in `.bashrc` for not only login sessions, but for new shells that need different settings, e.g. if you start an `xterm` from `gnome-terminal` and want different `dircolors`. – Mikel Jun 02 '12 at 03:06
  • @Mikel If you set environment variables in `.bashrc`, they will override your previous settings. For example, if you've started a Screen or Tmux instance with particular environment variables, anything you set in `.bashrc` will override these settings. `LS_COLORS` is a special case because it's really a per-terminal setting; ideally it should be set by the terminal emulator, and setting it in a shell rc file is a best-effort workaround. – Gilles 'SO- stop being evil' Jun 02 '12 at 13:41
1

In Gentoo documentation there is article Gentoo Linux Localization Guide. Chapter 3 is about setting locale.

Most typically users only set the LANG variable on the global basis. This example is for a unicode German locale:

Code Listing 3.1: Setting the default system locale in /etc/env.d/02locale

LANG="en_GB.UTF-8"

In my Gentoo LANG is set in this file and everything is working properly...

pbm@tauri ~ $ cat /etc/env.d/02locale 
LANG="pl_PL.UTF-8"

pbm@tauri ~ $ locale
LANG=pl_PL.UTF-8
LC_CTYPE="pl_PL.UTF-8"
LC_NUMERIC="pl_PL.UTF-8"
LC_TIME="pl_PL.UTF-8"
LC_COLLATE="pl_PL.UTF-8"
LC_MONETARY="pl_PL.UTF-8"
LC_MESSAGES="pl_PL.UTF-8"
LC_PAPER="pl_PL.UTF-8"
LC_NAME="pl_PL.UTF-8"
LC_ADDRESS="pl_PL.UTF-8"
LC_TELEPHONE="pl_PL.UTF-8"
LC_MEASUREMENT="pl_PL.UTF-8"
LC_IDENTIFICATION="pl_PL.UTF-8"
LC_ALL=
pbm
  • 24,747
  • 6
  • 36
  • 51
  • Beware that the part you quoted is ok, but the guide also recommends setting an environment variable in `.bashrc`, which is wrong (see my answer and in particular http://superuser.com/questions/217431). – Gilles 'SO- stop being evil' Dec 07 '10 at 20:50
  • Thanks for so detailed info... :) I've never used that .bashrc part - settings in `env.d` are more universal. – pbm Dec 07 '10 at 21:00
  • Also it is per system instead of per-user. I prefer to keep system settings separate from user settings. – Maciej Piechotka Dec 07 '10 at 22:47