export GOPATH=~/mygo:~/go
export GOBIN=$GOPATH/bin
我预计$GOBIN
等于~/mygo/bin:~/go/bin
,但它是~/mygo:~/go/bin
。
我怎么能让他们更好的方式? THX
答案 0 :(得分:0)
export GOPATH=~/mygo:~/go
export GOBIN=${(j<:>)${${(s<:>)GOPATH}/%//bin}}
虽然任何使用GOPATH
的程序都可能将其解释为数组,但对于zsh
,它只是一个标量(&#34;字符串&#34;)。
为了将字符串(/bin
)附加到字符串&#34; $ GOPATH&#34;首先需要拆分成一个数组。在zsh
中,可以使用参数扩展标志 s:string:
来完成此操作。这会在string
上拆分标量并返回一个数组。可以使用:
,()
,[]
或{}
代替<>
任何其他字符或匹配的string
对。在这种情况下,必须完成,因为:
是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
也可以在没有参数扩展标志或嵌套替换的情况下执行此操作,只需将:
附加到字符串的末尾并另外替换每个{ {1}} /bin:
:
export GOBIN=${GOPATH//://bin:}/bin
${name//pattern/repl}
扩展会将pattern
的所有出现替换为repl
,而不是仅使用${name/pattern/repl}
取代第一次出现。
这也适用于bash
。
就我个人而言,我觉得它有点&#34; hackish&#34;,主要是因为你需要两次写/bin
并且因为它完全回避了潜在的语义。但这只是个人偏好,结果将是相同的。
像在问题中一样定义GOPATH
时
export GOPATH=~/mygo:~/go
zsh
会使用您的主目录扩展~/
的每次出现。因此,GOPATH
的值将为/home/kevin/mygo:/home/kevin/go
- 假设用户名为&#34; kevin&#34;。因此,GOBIN
也将包含展开的路径/home/kevin/mygo/bin:/home/kevin/go/bin
,而不是~/mygo/bin:~/go/bin
这可以通过引用值GOPATH="~/mygo:~/go"
来防止 - 但我建议不要这样做。 ~
作为主目录的同义词不是操作系统的一项功能,虽然shell通常支持它,但其他程序(需要GOPATH
或GOBIN
的程序)可能不会这样做。