如何解决zshrc无法识别自定义bash函数
我最近从bash迁移到zsh,并且像大多数人一样,我具有自定义的bash别名/函数来简化git和env的采购操作。特别是其中有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 "$1"
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
git checkout "$1"
if [ $(pwd) == $REPO_ROOT ]; then
subroot
else
croot
fi
}
这个想法是我有一组main_repo-submodule分支,当我检出主仓库时,我想检出相应分支中的子模块,而不是这样做:
$ git submodule update --init --recursive subrepo/subrepo_1
它检出子模块中的正确提交,但不会更新我切换到某个本地分支的信息。
对于上一个功能,运行时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 "(^|:)$2(:|\$)" > /dev/null ; then
declare -g $1="${!1}:$2"
export "$1"
fi
}
# GENERATED BINARY A
export BIN_A_HOME="$REPO_ROOT/bin_a"
add2path PATH "$BIN_A_HOME/bin"
与某些生成的python模块相同,这些模块使用相同的add2path添加到PYTHONPATH
删除错误的地方:
add2path:1: bad substitution
解决方法
两个函数都使用在zsh中无效的bashisms。
在repcheckout
中,问题是在==
测试中使用[ ]
运算符-标准运算符为=
,但是bash允许==
为同义词zsh没有。我还建议对两个字符串都加双引号,以免路径中出现奇怪的字符(并可能使用"$PWD"
而不是$(pwd)
):
if [ "$PWD" = "$REPO_ROOT" ]; then
在add2path
中,问题是${!1}
和echo
命令中的间接变量引用declare
。 zsh还允许间接变量引用,但其语法完全不同:${(P)1}
。您可能会使用eval
来创建交叉兼容的版本,但是如果您使用不正确的话,这往往会导致奇怪的错误。我只是按照zsh的需要重写功能。
编辑:如果要在bash和zsh下使用相同的代码,eval
可能比尝试检测您所在的shell并根据其使用条件代码要好。这是编写跨外壳兼容版本的捷径:
if ! eval "echo \"\$$1\"" | egrep "(^|:)$2(:|\$)" > /dev/null ; then
eval "declare -g $1=\"\$$1:\$2\""
export "$1"
...
引号很难看,但只要$1
包含有效的标识符,它就可以正常工作;如果不是这样,通常的eval
问题可能会抬起头来。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。