Go + Git Bash の環境変数のファイルパスの扱いの面白い挙動
windows, Git Bash 上で AQUA_GLOBAL_CONFIG (;
区切りでファイルのパスが指定される)の扱いが妙なので調べたら、 複数のファイルパスを指定した場合 Unix 形式のパスが変換されてないことに気づいた。
というか os.Getenv で Unix 形式のパスが変換されているのが興味深い。
$ export AQUA_GLOBAL_CONFIG='/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
D:/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
;
$ export AQUA_GLOBAL_CONFIG='foo;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
foo;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
;
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Getenv("AQUA_GLOBAL_CONFIG"))
fmt.Println(string(os.PathListSeparator))
}
で、ここで問題なのが Unix 形式のパスだとファイルが見つけられないこと。
os.Getenv の段階で問題になってると辛いな。自分で変換できるのかな。
windows の形式にすれば問題ないが、 Git Bash であれば Unix 形式も処理できてほしい気もする。
export AQUA_GLOBAL_CONFIG='foo;D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml'
上の例だと何が問題なのかわかりにくい気がしたので修正。
D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
は読めているが /d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
は読めていない。
環境変数が /d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
の場合 os.Getenv の段階で D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
に変換されているが、 foo;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
を filepath.SplitList で分割しても変換されないので、ファイルが読めない。
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
fmt.Println(string(os.PathListSeparator))
fmt.Println(os.Getenv("AQUA_GLOBAL_CONFIG"))
for _, p := range filepath.SplitList(os.Getenv("AQUA_GLOBAL_CONFIG")) {
if _, err := os.Stat(p); err != nil {
fmt.Println("file doesn't exit:", p)
} else {
fmt.Println("file exits:", p)
}
}
}
$ echo $AQUA_GLOBAL_CONFIG
foo;D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
$ go run main.go
;
foo;D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
file doesn't exit: foo
file exits: D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
$ export AQUA_GLOBAL_CONFIG='foo;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
;
foo;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
file doesn't exit: foo
file doesn't exit: /d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
$ export AQUA_GLOBAL_CONFIG='/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
;
D:/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
file exits: D:/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
Go とか Git Bash じゃなくて mingw の問題かもしれない
試しに os.Setenv, Getenv をしてみたが、変換されなかった。
:
つなぎだと変換されているな?
AQUA_GLOBAL_CONFIG: /d/a/aqua/aqua/tests/aqua-global.yaml:/d/a/aqua/aqua/tests/aqua-global-2.yaml
time="2022-06-21T03:36:40Z" level=debug msg="checking a global configuration file" aqua_version= config_file_path="D:\\a\\aqua\\aqua\\tests\\aqua-global.yaml" env=windows/amd64 program=aqua
-
foo:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
はだめ -
/d/Users:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
は OK -
/d/Users;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
は だめ
POSIX 形式で絶対パスだと OK
$ export AQUA_GLOBAL_CONFIG='foo:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
;
foo:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
file doesn't exit: foo:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
$ export AQUA_GLOBAL_CONFIG='/d/Users:/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
;
D:\Users;D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
file exits: D:\Users
file exits: D:\Users\shunsukesuzuki\workspace\aqua-registry\aqua-all.yaml
$ export AQUA_GLOBAL_CONFIG='/d/Users;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml'
$ go run main.go
;
/d/Users;/d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml
file doesn't exit: /d/Users
file doesn't exit: /d/Users/shunsukesuzuki/workspace/aqua-registry/aqua-all.yaml