0
export GOPATH=~/mygo:~/go
export GOBIN=$GOPATH/bin

我期待$GOBIN平等~/mygo/bin:~/go/bin,但事实并非如此~/mygo:~/go/bin。我怎样才能为他们设置更好的方法?谢谢

4

1 回答 1

1

解决方案

export GOPATH=~/mygo:~/go
export GOBIN=${(j<:>)${${(s<:>)GOPATH}/%//bin}}

解释

尽管使用的任何程序都GOPATH可能将其解释为数组,因为zsh它只是一个标量(“字符串”)。

为了将字符串 ( /bin) 附加到每个元素,首先需要将字符串 "$GOPATH" 拆分为一个数组。这zsh可以通过参数扩展标志 s:string:来完成。这会拆分一个标量string并返回一个数组。代替:任何其他字符或匹配的(), [],{}<>可以使用。在这种情况下,它必须完成,因为stringis to be :

GOPATH_ARRAY=(${(s<:>)GOPATH)

现在${name/pattern/repl} 参数扩展可用于附加/bin到每个元素,或者更确切地说,将每个元素的末尾替换为/bin. 为了匹配字符串的结尾,pattern需要以 . 开头%。由于应匹配任何字符串,因此该模式为空:

GOBIN_ARRAY=(${GOPATH_ARRAY/%//bin})

最后,需要将数组转换回以冒号分隔的字符串。这可以通过j:string: 参数扩展标志来完成。它对应于s:string:

GOBIN=${(j<:>)GOBIN_ARRAY}

幸运的是,它zsh允许嵌套替换,因此可以在一条语句中完成所有操作,无需中间变量:

GOBIN=${(j<:>)${${(s<:>)GOPATH}/%//bin}}

替代解决方案

也可以在没有参数扩展标志嵌套替换的情况下执行此操作,只需附加/bin到字符串的末尾并另外将每个替换:/bin:

export GOBIN=${GOPATH//://bin:}/bin

${name//pattern/repl}扩展替换了每次出现的withpatternrepl不是第一次出现的 like with ${name/pattern/repl}

这也适用于bash.

个人觉得有点“hackish”,主要是你需要写/bin两次,也因为它完全回避了底层语义。但这只是个人喜好,结果是一样的。


笔记:

GOPATH像您在问题中所做的那样定义时

export GOPATH=~/mygo:~/go

zsh~/将使用您的主目录扩展每个出现的位置。所以值GOPATH将是/home/kevin/mygo:/home/kevin/go- 假设用户名是“kevin”。因此,GOBIN也将具有扩展路径,/home/kevin/mygo/bin:/home/kevin/go/bin而不是~/mygo/bin:~/go/bin

这可以通过引用值来防止GOPATH="~/mygo:~/go"- 但我建议不要这样做。~由于主目录的同义词不是操作系统的功能,虽然 shell 通常支持它,但其他程序(需要GOPATHor的程序GOBIN)可能不这样做。

于 2018-06-08T09:15:38.183 回答