将别名转发给子进程

将别名转发给子进程

/etc/zprofile我有一些在(或/etc/profilebash)中定义的别名。也在$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毫无用处。-llogin

相关内容