bash - 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
它检查了子模块中的正确提交,但没有更新我切换到某个本地分支。
前面的func,运行时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"
与使用相同 add2path 添加到 PYTHONPATH 的一些生成的 python 模块相同
这会导致错误:
add2path:1: bad substitution
解决方案
这两个函数都使用在 zsh 中无效的 bashism。
在repcheckout
中,问题在于==
在测试中使用运算符[ ]
——标准运算符是=
,但 bash 允许==
作为同义词;zsh 没有。我还建议双引号两个字符串以避免路径中出现奇怪字符的问题(并且可能使用"$PWD"
而不是$(pwd)
):
if [ "$PWD" = "$REPO_ROOT" ]; then
在中,问题是和命令中add2path
的间接变量引用。zsh 也允许间接变量引用,但它的语法完全不同:. 您可能可以创建一个与 交叉兼容的版本,但是如果您没有完全正确地使用它,这往往会导致奇怪的错误;我只是根据 zsh 的需要重写函数。${!1}
echo
declare
${(P)1}
eval
编辑:如果您想在 bash 和 zsh 下使用相同的代码,eval
可能比尝试检测您所在的 shell 并使用基于此的条件代码更好。这是编写跨外壳兼容版本的快速尝试:
if ! eval "echo \"\$$1\"" | egrep "(^|:)$2(:|\$)" > /dev/null ; then
eval "declare -g $1=\"\$$1:\$2\""
export "$1"
...
引用很难看,但只要$1
包含有效的标识符,它就可以正常工作;如果不是这样,通常的eval
问题可能会引起他们的丑陋。
推荐阅读
- scala - sbt 返回依赖问题
- javascript - 考虑随时间的加速度和减速度的对象插值
- python - 对于 leetcode.com 中的问题,如何在自己的 IDE 中正确输入自己的测试用例?
- java - 在itext7中,各种栏目文件或切换栏目文件
- python - 使用 BeautifulSoup 获取正确的标签(问题)
- django - 有没有办法以任何 url 模式添加 makemigration 和迁移?
- php - 两个单独的 MongoDB 集合将结果组合起来循环,没有关系
- javascript - 如果反应图中超过 2 个,则查看更多带有计数的按钮
- javascript - WebRTC - RTCDataChannel 的 onmessage 事件未触发
- heroku - Problem with deploying my first streamlit app on heroku