zshrc 无法识别自定义 bash 函数
zshrc doesn't recognize custom bash functions
我最近从 bash 转移到 zsh,和大多数人一样,我有自己的习惯 bash aliases/functions 来简化 git 和环境采购操作。特别是其中有 2 个在 zsh 上 运行 时不能正常工作,但在 bash.
上工作完全正常
export REPO_ROOT=/home/pablo/repos/my_repo
alias croot='cd $REPO_ROOT'
alias subroot='cd $REPO_ROOT/subrepo/subrepo_1/'
repcheckout(){
git checkout ""
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
git checkout ""
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
}
我的想法是我有一组 main_repo-submodule 个分支,当我签出主仓库时,我想签出相应分支中的子模块,而不是:
$ git submodule update --init --recursive subrepo/subrepo_1
它检查子模块中的正确提交但不更新我切换到某个本地分支。
之前的func,运行ning
时zsh掉的错误
$ repcheckout my_cool_branch
是
M subrepo/subrepo_1/
Switched to branch 'my_cool_branch'
repcheckout:2: = not found
稍后我有一个 setup.sh 源文件,如下所示:
add2path() {
if ! echo ${!1} | egrep "(^|:)(:|$)" > /dev/null ; then
declare -g ="${!1}:"
export ""
fi
}
# GENERATED BINARY A
export BIN_A_HOME="$REPO_ROOT/bin_a"
add2path PATH "$BIN_A_HOME/bin"
与使用相同的 add2path
添加到 PYTHONPATH 的一些生成的 python 模块相同
丢弃错误:
add2path:1: bad substitution
这两个函数都使用 bash在 zsh 中无效的主义。
在 repcheckout
中,问题是在 [ ]
测试中使用 ==
运算符——标准运算符是 =
,但 bash 允许==
作为同义词; zsh 没有。我还建议 double-quoting 这两个字符串以避免路径中出现奇怪字符的问题(并且可能使用 "$PWD"
而不是 $(pwd)
):
if [ "$PWD" = "$REPO_ROOT" ]; then
在add2path
中,问题是echo
和declare
命令中的间接变量引用${!1}
。 zsh 也允许间接变量引用,但它的语法完全不同:${(P)1}
。你可能会用 eval
制作一个 cross-compatible 版本,但如果你没有完全正确地使用它,那往往会导致奇怪的错误;我只是根据 zsh 的需要重写函数。
编辑:如果您想在 bash 和 zsh 下使用相同的代码,eval
可能比尝试检测您所在的 shell 并使用条件更好基于此的代码。这是编写 cross-shell 兼容版本的快速尝试:
if ! eval "echo \"$\"" | egrep "(^|:)(:|$)" > /dev/null ; then
eval "declare -g =\"$:$2\""
export ""
...
引用很丑陋,但只要 </code> 包含有效标识符,它就可以正常工作;否则,常见的 <code>eval
问题可能会浮出水面。
我最近从 bash 转移到 zsh,和大多数人一样,我有自己的习惯 bash aliases/functions 来简化 git 和环境采购操作。特别是其中有 2 个在 zsh 上 运行 时不能正常工作,但在 bash.
上工作完全正常export REPO_ROOT=/home/pablo/repos/my_repo
alias croot='cd $REPO_ROOT'
alias subroot='cd $REPO_ROOT/subrepo/subrepo_1/'
repcheckout(){
git checkout ""
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
git checkout ""
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
}
我的想法是我有一组 main_repo-submodule 个分支,当我签出主仓库时,我想签出相应分支中的子模块,而不是:
$ git submodule update --init --recursive subrepo/subrepo_1
它检查子模块中的正确提交但不更新我切换到某个本地分支。
之前的func,运行ning
时zsh掉的错误$ repcheckout my_cool_branch
是
M subrepo/subrepo_1/
Switched to branch 'my_cool_branch'
repcheckout:2: = not found
稍后我有一个 setup.sh 源文件,如下所示:
add2path() {
if ! echo ${!1} | egrep "(^|:)(:|$)" > /dev/null ; then
declare -g ="${!1}:"
export ""
fi
}
# GENERATED BINARY A
export BIN_A_HOME="$REPO_ROOT/bin_a"
add2path PATH "$BIN_A_HOME/bin"
与使用相同的 add2path
添加到 PYTHONPATH 的一些生成的 python 模块相同丢弃错误:
add2path:1: bad substitution
这两个函数都使用 bash在 zsh 中无效的主义。
在 repcheckout
中,问题是在 [ ]
测试中使用 ==
运算符——标准运算符是 =
,但 bash 允许==
作为同义词; zsh 没有。我还建议 double-quoting 这两个字符串以避免路径中出现奇怪字符的问题(并且可能使用 "$PWD"
而不是 $(pwd)
):
if [ "$PWD" = "$REPO_ROOT" ]; then
在add2path
中,问题是echo
和declare
命令中的间接变量引用${!1}
。 zsh 也允许间接变量引用,但它的语法完全不同:${(P)1}
。你可能会用 eval
制作一个 cross-compatible 版本,但如果你没有完全正确地使用它,那往往会导致奇怪的错误;我只是根据 zsh 的需要重写函数。
编辑:如果您想在 bash 和 zsh 下使用相同的代码,eval
可能比尝试检测您所在的 shell 并使用条件更好基于此的代码。这是编写 cross-shell 兼容版本的快速尝试:
if ! eval "echo \"$\"" | egrep "(^|:)(:|$)" > /dev/null ; then
eval "declare -g =\"$:$2\""
export ""
...
引用很丑陋,但只要 </code> 包含有效标识符,它就可以正常工作;否则,常见的 <code>eval
问题可能会浮出水面。