goのos.Openは~を見てくれないっぽい。
~はだめ
os.Openは"~“をhome directoryとして空気を読んで良い感じに解釈してくれないっぽい。
// 01tilda.go package main import ( "io" "log" "os" ) func main() { filename := "~/.screenrc" f, err := os.Open(filename) if err != nil { log.Fatal(err) } defer f.Close() io.Copy(os.Stdout, f) }
ダメっぽい。
$ go run 01tilda.go 2017/06/01 08:47:59 open ~/.screenrc: no such file or directory exit status 1
$HOMEもだめっぽい
$HOME
も同様にダメっぽい
package main import ( "io" "log" "os" ) func main() { filename := "$HOME/.screenrc" f, err := os.Open(filename) if err != nil { log.Fatal(err) } defer f.Close() io.Copy(os.Stdout, f) }
$ go run 02env.go 2017/06/01 08:51:04 open $HOME/.screenrc: no such file or directory exit status 1
コマンドライン引数で渡された場合はshellが解釈してくれるので大丈夫
package main import ( "io" "log" "os" ) func main() { filename := os.Args[1] f, err := os.Open(filename) if err != nil { log.Fatal(err) } defer f.Close() io.Copy(os.Stdout, f) }
こちらは大丈夫(対象が ~/.screenrc
である理由はとくに無い)。
go run 03cmd.go ~/.screenrc escape ^Jj autodetach on defscrollback 3000 vbell off hardstatus alwayslastline "%{= rw} %H %{= wk}%-Lw%{= bw}%n%f* %t%{= wk}%+Lw %{= wk}%=%{= gk} %y/%m/%d %c "
というか
~
も $HOME
もshellによって解釈されるものなのでos.Openに渡されるパスは変換後のパスを期待するという感じっぽい?
頑張って治さないといけないっぽい。
横着するなら、環境変数から$HOMEを取り出すだったり、os/userからHomeDirを取り出すだったりする。
gore version 0.2.6 :help for help gore> :import os gore> :import strings gore> strings.Replace("~/.screenrc", "~", os.Getenv("HOME"), 1) "/Users/podhmo/.screenrc" gore> :import os/user gore> u, _ := user.Current() &user.User{ Uid: "501", Gid: "20", Username: "podhmo", Name: "podhmo", HomeDir: "/Users/podhmo", } gore> strings.Replace("~/.screenrc", "~", u.HomeDir, 1) "/Users/podhmo/.screenrc"
それかこの辺を使う。