在 .zshrc 配置中使用 var multi GOPATH 设置 GOBIN 根目录
GOBIN root setting with var multi GOPATH in .zshrc config
export GOPATH=~/mygo:~/go
export GOBIN=$GOPATH/bin
我希望 $GOBIN
等于 ~/mygo/bin:~/go/bin
,但它是 ~/mygo:~/go/bin
。
我怎样才能更好地设置它们?谢谢
解决方案
export GOPATH=~/mygo:~/go
export GOBIN=${(j<:>)${${(s<:>)GOPATH}/%//bin}}
说明
尽管任何使用 GOPATH
的程序都可能将其解释为数组,但对于 zsh
它只是一个标量 ("string")。
为了将字符串 (/bin
) 附加到每个元素,首先需要将字符串“$GOPATH”拆分为一个数组。在 zsh
中,这可以通过 参数扩展标志 s:string:
来完成。这会在 string
和 returns 数组上拆分一个标量。可以使用任何其他字符或 ()
、[]
、{}
或 <>
来代替 :
。在这种情况下,必须这样做,因为 string
是 :
.
GOPATH_ARRAY=(${(s<:>)GOPATH)
现在 ${name/pattern/repl}
参数扩展 可用于将 /bin
附加到每个元素,或者更确切地说用 [= 替换每个元素的末尾19=]。为了匹配字符串的结尾,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}
扩展将 pattern
的每次出现替换为 repl
而不是像 ${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 通常支持它,但其他程序(那些需要 GOPATH
或 GOBIN
的程序)可能不会这样做。
export GOPATH=~/mygo:~/go
export GOBIN=$GOPATH/bin
我希望 $GOBIN
等于 ~/mygo/bin:~/go/bin
,但它是 ~/mygo:~/go/bin
。
我怎样才能更好地设置它们?谢谢
解决方案
export GOPATH=~/mygo:~/go
export GOBIN=${(j<:>)${${(s<:>)GOPATH}/%//bin}}
说明
尽管任何使用 GOPATH
的程序都可能将其解释为数组,但对于 zsh
它只是一个标量 ("string")。
为了将字符串 (/bin
) 附加到每个元素,首先需要将字符串“$GOPATH”拆分为一个数组。在 zsh
中,这可以通过 参数扩展标志 s:string:
来完成。这会在 string
和 returns 数组上拆分一个标量。可以使用任何其他字符或 ()
、[]
、{}
或 <>
来代替 :
。在这种情况下,必须这样做,因为 string
是 :
.
GOPATH_ARRAY=(${(s<:>)GOPATH)
现在 ${name/pattern/repl}
参数扩展 可用于将 /bin
附加到每个元素,或者更确切地说用 [= 替换每个元素的末尾19=]。为了匹配字符串的结尾,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}
扩展将 pattern
的每次出现替换为 repl
而不是像 ${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 通常支持它,但其他程序(那些需要 GOPATH
或 GOBIN
的程序)可能不会这样做。