4

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.

  • 1
    Running zsh does not load /etc/zprofile. Did you in fact mean /etc/zshrc? Or does /etc/zshrc explicitly load /etc/zprofile? Can you modify your home directory files? Post the content of /etc/zprofile, /etc/zshrc and any other relevant file. You don't necessarily have to post the whole, actual content if there are thing there that are private, but post complete code that reproduces the problem. With what you've posted now, your question does not make sense since running zsh does not load /etc/zprofile yet you claim it does. – Gilles May 25 '16 at 11:15
3

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 run zsh 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

tmp=$(mktemp -d)
alias -L >$tmp/.zshenv
echo ". ~/.zshenv; unset ZDOTDIR; rm -r ${(q)tmp}" >>$tmp/.zshenv
zsh
  • I don't have permissions to manipulate /etc/zprofile, so as bad as it may be that the definitions are there, I can't move them away from there. – pseyfert May 25 '16 at 8:47
  • Also (that was unclear in the original post) the zsh I'm starting is supposed to be interactive (as in: I don't want it to execute a script. I want to do "normal shell things" in it: typing, tabbing, opening editors, executing executables, cd'ing) – pseyfert May 25 '16 at 8:59
2

In bash

You can abuse the --rcfile option like so:

bash --noprofile --rcfile <(alias)

But the --noprofile is pretty useless without the -l option to make it a login shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.