/etc/zprofile
我有一些在(或/etc/profile
bash)中定义的别名。也在$PATH
那里被操纵。
我想从避免操作的 shell 启动交互式 shell $PATH
。我通过使用-f
选项启动它来做到这一点。然而,在父 shell 中定义的别名很有用,我想将它们转发给子进程。
将一次定义的别名复制并粘贴/etc/zprofile
到文本文件中,并在每次启动另一个 shell 时获取它,这并不是我想要的,因为定义会/etc/zprofile
得到维护,并且可能会随着时间的推移而改变。
您对如何将别名转发到第二个 shell 有建议吗?
(我的主要兴趣是解决方案,但我也zsh
对解决方案感到好奇)bash
我认为情况是这样的
# 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
继续提供信息;中的内容/etc
比我最初想象的要复杂:
/etc/zprofile
包含以下内容,我追踪到这些内容定义了我的别名和$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
但我错过了其中/etc/zshrc
包含
_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
所以它不仅zprofile
会经历/etc/profile.d
,而且还会经历zshrc
。其中一个文件/etc/profile.d
就是这样(我添加了关于它如何进行的注释)
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
最终/my/group/path/group_zshrc
调用一个Python程序,该程序写入一个临时文件,在其中定义/操作别名和环境变量,然后最终获取该临时文件。
答案1
您不应该在/etc/zprofile
或中定义别名~/.zprofile
。这些文件仅在登录 shell 中加载(“shell”当然是指 zsh)。定义别名的正确位置是/etc/zshrc
或~/.zshrc
,所有交互式 shell 都会读取它。
要在不加载的情况下运行 zsh /etc/zprofile
,只需zsh
不带任何选项运行即可。该选项-f
告诉 zsh 根本不读取配置文件,但由于您想读取别名定义,所以这不是正确的选项。由于/etc/zprofile
只能由登录 shell 读取,因此只需不传递-l
选项(并且不要设置以破折号开头的第零个参数)。
Zsh 没有选项或环境变量来在启动时读取一个额外的文件。如果您想为此做好准备,您可以将其添加eval $ZSH_EXTRA_STARTUP_CODE
到您的.zshrc
.
您可以设置ZDOTDIR
环境变量以使其从不同的目录读取所有用户配置文件,例如ZDOTDIR=/tmp/foo zsh
读取/etc/zshenv
、/tmp/foo/.zshenv
和。因此,要将别名从当前实例导出到子实例,您可以运行类似的命令/etc/zshrc
/tmp/foo/zshrc
tmp=$(mktemp -d)
alias -L >$tmp/.zshenv
echo ". ~/.zshenv; unset ZDOTDIR; rm -r ${(q)tmp}" >>$tmp/.zshenv
zsh
答案2
在bash
您可以--rcfile
像这样滥用该选项:
bash --noprofile --rcfile <(alias)
但是如果没有选择将其作为外壳,那么它就--noprofile
毫无用处。-l
login