I have some aliases which are defined in /etc/zprofile
(or /etc/profile
for bash). Also $PATH
gets manipulated there.
I want to start an interactive shell from a shell which avoids the $PATH
manipulation. I do this by starting it with the -f
option. Yet, the aliases which are defined in the parent shell are useful and I'd like to forward them to the child process.
Copy and pasting the aliases which are defined by /etc/zprofile
once into a text file and sourcing it every time I start another shell is not what I'm looking for as the definitions in /etc/zprofile
get maintained and may change over time.
Do you have a recommendation how to forward aliases to the second shell?
(My main interest are zsh
solutions, but I'm curious about bash
solutions as well)
This is how the situation looks to me
# log in with ssh
shell1 > echo "here aliases are the way I want them to be"
shell1 > VARIABLE1=value1 VARIABLE2=value2 PATH=some_paths zsh
shell2 > echo "/etc/zprofile prepended something to PATH, which I don't like"
shell2 > echo "aliases are good"
shell2 > exit
shell1 > VARIABLE1=value1 VARIABLE2=value2 PATH=some_paths zsh -f
shell2 > echo "/etc/zprofile did not prepend something to PATH. This is good!"
shell2 > echo "but all aliases from shell 1 are \"forgotten\""
shell2 > exit
Continuing to provide information; the things in /etc
are more involved than I initially thought:
/etc/zprofile
contains the following, which I traced down to be what defines my aliases and $PATH
_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
but I missed that /etc/zshrc
contains
_src_etc_profile_d()
{
# Make the *.sh things happier, and have possible ~/.zshenv options like
# NOMATCH ignored.
emulate -L ksh
# from bashrc, with zsh fixes
if [[ ! -o login ]]; then # We're not a login shell
for i in /etc/profile.d/*.sh; do
if [ -r "$i" ]; then
. $i
fi
done
unset i
fi
}
_src_etc_profile_d
unset -f _src_etc_profile_d
so it's not only zprofile
which goes through /etc/profile.d
but also zshrc
. One of the files in /etc/profile.d
does then (with comments added by me for how it goes on)
if [ -n "$SHLVL" ]; then
if [ $SHLVL = 1 ]; then
source /some/group/path/profile
# calls "source /some/group/path/env"
# -> see else branch
else
source /some/group/path/env
# calls "source /some/group/path/${SHELL}rc"
# which then calls
# "source /my/group/path/group_zshrc"
fi
else
echo 'No $SHLVL available, assuming login shell.'
source /some/group/path/profile
fi
and ultimately /my/group/path/group_zshrc
calls a python program which writes a temporary file in which aliasses and environment variables are defined / manipulated, which is then sourced in the end.
Best Answer
You shouldn't define aliases in
/etc/zprofile
or~/.zprofile
. These files is only loaded in login shells (“shells” meaning zsh of course). The proper place to define aliases is in/etc/zshrc
or~/.zshrc
, which is read by all interactive shells.To run zsh without loading
/etc/zprofile
, just runzsh
with no option. The option-f
tells zsh not to read configuration files at all, but since you want to read your alias definitions, that's not the right option. Since/etc/zprofile
is only read by a login shell, just don't pass the-l
option (and don't set a zeroth argument that begins with a dash).Zsh has no option or environment variable to read one extra file on startup. If you want to prepare for that, you can add
eval $ZSH_EXTRA_STARTUP_CODE
to your.zshrc
.You can set the
ZDOTDIR
environment variable to make it read all of its user configuration files from a different directory, e.g.ZDOTDIR=/tmp/foo zsh
reads/etc/zshenv
,/tmp/foo/.zshenv
,/etc/zshrc
and/tmp/foo/zshrc
. So to export aliases from the current instance to a child instance, you can run something like