Closed VorpalBlade closed 1 year ago
z4h does not source global rc files by design. If you want to source /etc/zsh/zprofile
, add ~/.zprofile
with the following content:
z4h source /etc/zsh/zprofile
FWIW, I would strongly recommend NOT sourcing /etc/zsh/zprofile
. If there are individual files in there that you want, either source them directly or (better yet), copy the content you care about into your own user rc files. The latter usually allows you to remove the crap that inevitably accompanies the rare useful bits found in global rc files. You can often make the code orders of magnitude faster, too.
Thanks for the quick reply! After looking through those files I think a better approach is to pick and choose which parts I want, as some (such as vte.sh) seem highly problematic when using z4h.
Doing that is not completely trivial though (this is mostly for the benefit of anyone else who runs into this and finds this bug):
append_path
defined in /etc/profile which is unset before /etc/profile returns. append_path basically ensures there are no duplicates in path (so mostly for the benefit of bash). Still an analog needs to be provided to allow sourcing those files individually.
- Several of them depend on the function
append_path
defined in /etc/profile which is unset before /etc/profile returns. append_path basically ensures there are no duplicates in path (so mostly for the benefit of bash). Still an analog needs to be provided to allow sourcing those files individually.
You can modify path like this:
# Append.
path+=(/some/dir)
# Prepend.
path=(/some/dir $path)
There won't be dups.
You can also add dirs only if they exist, which is nice for performance. Like this:
path+=(/some/dir(/N))
z4h already has all the useful bits of vte.sh
. As usual, a rewrite makes it 1000 times faster and avoids silly bugs.
The problem with copying things into my own files is that some of that stuff is distro specific. Since I use the same z4h setup (using chezmoi) on multiple distros (Arch and Debian), that would complicate things. And then there is the issue of keeping up with future updates of course.
Currently I'm thinking something like this could work:
append_path() { PATH="$PATH:$1" }
for profile_part in debuginfod.sh locale.sh; do
if [[ -f /etc/profile.d/$profile_part ]]; then
emulate sh -c "source /etc/profile.d/$profile_part"
fi
done
unset append_path profile_part
It's virtually never distro specific. If you can show me a specific example, I might be able to show how to write it in zsh.
It appears that locale.sh (which caused the original bug I ran into with incorrect locales in root shells) is distro specific. One solution (and perhaps the cleanest one) is of course to not use /etc/locale.conf
but just set the locale I care about directly in the zshprofile.
~ ❯ cat /etc/profile.d/locale.sh
#!/bin/sh
# load locale.conf in XDG paths.
# /etc/locale.conf loads and overrides by kernel command line is done by systemd
# But we override it here, see FS#56688
if [ -z "$LANG" ]; then
if [ -n "$XDG_CONFIG_HOME" ] && [ -r "$XDG_CONFIG_HOME/locale.conf" ]; then
. "$XDG_CONFIG_HOME/locale.conf"
elif [ -n "$HOME" ] && [ -r "$HOME/.config/locale.conf" ]; then
. "$HOME/.config/locale.conf"
elif [ -r /etc/locale.conf ]; then
. /etc/locale.conf
fi
fi
# define default LANG to C if not already defined
LANG=${LANG:-C}
# export all locale (7) variables when they exist
export LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY \
LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT \
LC_IDENTIFICATION
~ ❯ pacman -Qo /etc/profile.d/locale.sh
/etc/profile.d/locale.sh is owned by filesystem 2022.10.18-1
Most other things (except debuginfod and locale) are only relevant in GUI sessions to me, and there it seems it is already sourced somehow by either the login manager SDDM or KDE.
Hm, exporting LC_* from .zprofile
does not seem to work for some weird reason. Only LANG seems to take effect.
export LANG=en_GB.UTF-8
export LC_NUMERIC=sv_SE.UTF-8
export LC_TIME=sv_SE.UTF-8
export LC_MONETARY=sv_SE.UTF-8
export LC_PAPER=sv_SE.UTF-8
export LC_MEASUREMENT=sv_SE.UTF-8
Does z4h mess with locales?
EDIT: More specifically something sets LC_ALL=C.UTF-8 when I log into a vt.
EDIT: More specifically something sets
LC_ALL=C.UTF-8
when I log into a vt.
If the current locale isn't UTF-8, z4h will set LC_ALL to a UTF-8 one.
It appears that locale.sh (which caused the original bug I ran into with incorrect locales in root shells) is distro specific.
This should do it:
[[ -n $LANG ]] || z4h source /etc/locale.conf
unset LC_ALL
C.UTF-8
is the best locale for the terminal for tech-minded people. It's the most "international" w.r.t. number formatting, dates, currency, etc. When posting the output of tools and asking others for help, it's best if that output is made with C.UTF-8
locale.
Ah, maybe it gets confused by my slightly complicated UTF-8 locale. LANG is set, and then I use some LC_* overrides.
Your suggestion doesn't do the right thing though, because locale.conf does not contain export (so it needs to be followed by some export commands.
As for C.UTF-8 being best. Yes, to some extent. I still need A4 (not letter paper), so LC_PAPER must be set to something European if I recall correctly. I prefer non-american date formats (who in their right mind uses middle endianness for the month!?), and so on. And weeks should start on Monday, not Sunday of course.
So there is an argument for setting LANG=C.UTF-8 and using various LC_* overrides. But I do prefer British spelling. :)
Thanks for the quick help even through z4h is on minimal maintenance mode!
I'm opening a separate issue that it is LANG that should be set, not LC_ALL though. After reading through man 7 locale this seems like the right option.
Ah, maybe it gets confused by my slightly complicated UTF-8 locale. LANG is set, and then I use some LC_* overrides.
Maybe it gets confused but it's more likely that whatever you set results in non-utf-8 encoding. You can check with this command:
zmodload zsh/langinfo && print -r -- ${langinfo[CODESET]}
Your suggestion doesn't do the right thing though, because locale.conf does not contain export (so it needs to be followed by some export commands.
You can use z4h source /etc/profile.d/locale.sh
. It's decent.
I'm opening a separate issue that it is LANG that should be set, not LC_ALL though. After reading through man 7 locale this seems like the right option.
LANG
won't override whatever parameters are setting a non-utf-8 locale. Having a non-utf-8 locale is a problem of much greater proportion than date formatting, so if the user ended up with a non-utf-8 locale, LC_ALL
it is.
LANG won't override whatever parameters are setting a non-utf-8 locale. Having a non-utf-8 locale is a problem of much greater proportion than date formatting, so if the user ended up with a non-utf-8 locale, LC_ALL it is.
Hm true, this only makes sense for the "no locale set yet" case, which is what I was running into (it seems LC_ALL is set during .zshenv, which is before .zprofile).
I guess it would be too complicated to detect that situation separately?
And I do end up with a UTF-8 locale. It is just that apparently .zprofile is after the LC_ALL check.
z4h sets locale in zshenv as early as possible because otherwise it's difficult to use the terminal at all. When changing locale, unset all parameters instead of patching them. Like this:
unset -m 'LC_*|LANG'
In my case (Fedora), instead of
z4h source /etc/zsh/zprofile
I had to use
source /etc/zprofile
in ~/.zprofile
, otherwise it seemingly wouldn't do anything. Probably because z4h is not yet configured?
And /etc/zprofile
contains:
#
# /etc/zprofile and ~/.zprofile are run for login shells
#
_src_etc_profile()
{
# Make /etc/profile happier, and have possible ~/.zshenv options like
# NOMATCH ignored.
#
emulate -L ksh
# source profile
if [ -f /etc/profile ]; then
source /etc/profile
fi
}
_src_etc_profile
unset -f _src_etc_profile
Then, when SDDM runs KDE, it launches a zsh login shell, which goes to $ZDOTDIR
, finds ~/.zprofile
, which in turn sources /etc/zprofile
, which sources the scripts under /etc/profile.d
in ksh emulation mode.
Now, things like .desktop files from flatpak are found by KRunner.
In my case (Fedora), instead of
z4h source /etc/zsh/zprofile
I had to use
source /etc/zprofile
in
~/.zprofile
, otherwise it seemingly wouldn't do anything. Probably because z4h is not yet configured?
z4h source /etc/zsh/zprofile
doesn't do anything on your machine because /etc/zsh/zprofile
does not exist.
No, that is not the reason. Sorry, I meant to write:
instead of
z4h source /etc/zprofile
I had to usesource /etc/zprofile
I have just tested it. E.g. with z4h
command I don't see the application entries in KDE menu, while with just sourcing they do show up.
I have just tested it. E.g. with
z4h
command I don't see the application entries in KDE menu, while with just sourcing they do show up.
This sounds very surprising given that all zsh configs that use zsh4humans utilize z4h source
command. I've just tried it on my machine and it works fine.
It appears when using z4h that
/etc/profile
is not sourced. This causes /etc/profile.d not to be sourced, which means things like /etc/locale.conf and debuginfod URIs are not set up.On a graphical login (KDE) these files are still sources (and then the environment inherited by graphical terminals). But when logging in on the virtual terminals (or when using
su -
), they appear to be ignored.On Arch Linux (which I use) the setup is as follows:
There are several of these I care about being sourced (such as locale and debuginfod) which sets relevant environment variables, as well as some that extend
PATH
, and similar. There are others (like vte.sh and gawk.sh) that are more questionable.Is this a z4h bug? Is it intentional? What is the preferred solution to this when using z4h? It is kind of hard to manually keep track of which ones I still want to source (and are relevant), and that might change over time, especially on a rolling release distro like Arch.