问题
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 foundpyenv
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:
- Disable the problematic configurations
- Open a terminal
- Check the value of
SHLVL
:echo $SHLVL
- Re-enable the configurations
- 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'. - Check the value of
SHLVL
again. If it is bigger then previous value then exit the current shell (exit
). (Explanation below) - 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