What is `-a` in a Zshell function and what does it have to do with my shell immediately exiting?

∥☆過路亽.° 提交于 2019-12-11 14:57:00

问题


I'm having an issue with my .zshrc file while using oh-my-zsh. Recently, I've started trying to be more careful about mucking with my base OS environment, so I installed Python (2 and 3) and pyenv using homebrew. While trying to configure the autocomplete for pyenv, I switched on the pyenv plugin in oh-my-zsh.

This resulted in my shell shutting down during the launch. I found that I could prevent this from happening by commenting out most of the active portion of the pyenv oh-my-zsh plugin, and I'm not sure why that's causing the shell to exit.

To make this question as concise as possible, I'd like to know what the following function does:

if [ -d $pyenvdir/bin -a $FOUND_PYENV -eq 0 ] 

The full code from the plugin follows:

_homebrew-installed() {
    type brew &> /dev/null
}

_pyenv-from-homebrew-installed() {
    brew --prefix pyenv &> /dev/null
}

FOUND_PYENV=0
pyenvdirs=("$HOME/.pyenv" "/usr/local/pyenv" "/opt/pyenv")
if _homebrew-installed && _pyenv-from-homebrew-installed ; then
    pyenvdirs=($(brew --prefix pyenv) "${pyenvdirs[@]}")
fi

for pyenvdir in "${pyenvdirs[@]}" ; do
    if [ -d $pyenvdir/bin -a $FOUND_PYENV -eq 0 ] ; then
        FOUND_PYENV=1
        export PYENV_ROOT=$pyenvdir
        export PATH=${pyenvdir}/bin:$PATH
        eval "$(pyenv init --no-rehash - zsh)"

        function pyenv_prompt_info() {
            echo "$(pyenv version-name)"
        }
    fi
done
unset pyenvdir

if [ $FOUND_PYENV -eq 0 ] ; then
    function pyenv_prompt_info() { echo "system: $(python -V 2>&1 | cut -f 2 -d ' ')" }
fi

From what I can tell, it goes something like this:

  • Check to see if there is a bin directory in one of the pyenvdirs (-d $pyenvdir/bin), ???? (-a), check to see if we already found pyenv previously ($FOUND_PYENV -eq 0).

I tried searching through the zsh documentation, but I can't figure out what the -a is doing. Is it as simple as behaving as an AND statement? If so, why is my shell crashing? Is there an easy way to push the shell output to a log file (on OS X), or is this already done and I just don't know where to look?


回答1:


What does -a do?

Here -a does indeed mean AND.

Why is it undocumented? Or is it?

The reason you did not find this in the zsh documentation is that the use of the [ builtin (aka test; it is not part of the zsh syntax) is discouraged in favour of conditional expressions (which are surrounded by [[ and ]]).

Here is the relevant part of zshbuiltins(1):

[ [ arg ... ] ]

Like the system version of test. Added for compatibility; use contitional expressions instead [...]

To find documentation on the parameter -a of [ have a look at test(1):

EXPRESSION1 -a EXPRESSION2

both EXPRESSION1 and EXPRESSION2 are true

What happens in the line with -a?

That means that this line

if [ -d $pyenvdir/bin -a $FOUND_PYENV -eq 0 ] 

First checks if $pyenvdir/bin exists and is a directory, than it checks if $FOUND_PYENV is equal to 0. If both are true the following block is executed.

Should it kill the shell?

There is no reason why this line should immediatelly lead to the shell exiting.


Looking for the error

All shell output goes to the terminal, so you could just redirect it when starting it. As you are looking for error messages during initialisation, I'd suggest the following procedure:

  1. Disable the problematic configurations
  2. Open a terminal
  3. Check the value of SHLVL: echo $SHLVL
  4. Re-enable the configurations
  5. Start a new z-shell from within the running shell with zsh 2> zsh-error.log, this redirects stderr to the file 'zsh-error.log'.
  6. Check the value of SHLVL again. If it is bigger then previous value then exit the current shell (exit). (Explanation below)
  7. Have a look at 'zsh-error.log' in the current directory.

If 'zsh-error.log' does not show anything, you may want to run zsh -x 2> zsh-error.log in step 5 instead. This provides a complete debug output of anything zsh does. This can get quite huge.

Explanation for SHLVL:

When a shell starts it looks if SHLVL is set on the environment. If so, it increases the value, else it initalizes SHLVL (usually with 1). If your shell started successfully in step 5, SHLVL should be increased. In that case you should stop the shell in order to keep the amount of output in the error log low. On the other hand, if SHLVL is unchanged, the shell terminated on its own and you are back in the original shell provided by the terminal in step 2.



来源:https://stackoverflow.com/questions/26051561/what-is-a-in-a-zshell-function-and-what-does-it-have-to-do-with-my-shell-imme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!