pyenvのpythonを叩くと自作goプログラムのpanicが走る怪奇現象
タイトルで出落ち。
結論
- ビルトインのコマンド名を自作プログラムに使うのはNG(大昔から言われてるからそれ
- 自作プログラムへのPATHは追加する形で(昔から(ry
- ソースコードリーディング楽しい(白目
きっかけ
算数をpythonにお願いしようとしたところ以下のエラーが発生した。
[User@PC] ~ % python panic: Head http://localhost:18888: dial tcp 127.0.0.1:18888: getsockopt: connection refused goroutine 1 [running]: main.main() /path/to/head/head.go:11 +0x16e [User@PC] ~
Goプログラムのソースは以下。書籍「Real World HTTP」の写経で、HTTPのHEADリクエストを送信するもの。
# Filename: head.go package main import ( "log" "net/http" ) func main() { resp, err := http.Head("http://localhost:18888") if err != nil { panic(err) } log.Println("Status: ", resp.Status) log.Println("Headers: ", resp.Header) }
解決への流れ
- pythonの確認
- pyenvの確認
- headの確認
- $PATHの確認
実際
pythonの確認
ブログ用にcat、実際にはless
[User@PC] ~ % file `which python` /path/to/.anyenv/envs/pyenv/shims/python: Bourne-Again shell script text executable, ASCII text [User@PC] ~ % cat `which python` #!/usr/bin/env bash set -e [ -n "$PYENV_DEBUG" ] && set -x program="${0##*/}" if [[ "$program" = "python"* ]]; then for arg; do case "$arg" in -c* | -- ) break ;; */* ) if [ -f "$arg" ]; then export PYENV_FILE_ARG="$arg" break fi ;; esac done fi export PYENV_ROOT="/path/to/.anyenv/envs/pyenv" exec "/path/to/.anyenv/envs/pyenv/libexec/pyenv" exec "$program" "$@" [User@PC] ~
※$programや$@にエラーになる要因がないかはechoさせて確認
ここでhead.goが正常動作する場合も確認しておいた。
pyenvのエラーが有用。pyenvの中にエラーの要因があると断定。
[User@PC] ~ % python 2017/12/23 13:57:03 Status: 200 OK 2017/12/23 13:57:03 Headers: map[Content-Length:[54] Content-Type:[text/html; charset=utf-8] Set-Cookie:[VISIT=TRUE] Date:[Sat, 23 Dec 2017 04:57:03 GMT]] pyenv: cannot find readlink - are you missing GNU coreutils?
Goの サーバプログラムは以下。これも上記書籍の写経。
package main import ( "fmt" "io/ioutil" "log" "net/http" "net/http/httputil" "github.com/k0kubun/pp" ) 〜中略〜 func main() { var httpServer http.Server http.HandleFunc("/", handler) httpServer.Addr = ":18888" log.Printf("[i] Start http listing %s\n", httpServer.Addr) log.Println(httpServer.ListenAndServe()) }
pyenvの確認
catの箇所では文字列検索をしたかったのでvimで開いた
[User@PC] ~ % file /path/to/.anyenv/envs/pyenv/libexec/pyenv /path/to/.anyenv/envs/pyenv/libexec/pyenv: Bourne-Again shell script text executable, ASCII text [User@PC] ~ % cat /path/to/.anyenv/envs/pyenv/libexec/pyenv ## 先ほどのエラー「pyenv: cannot find readlink - are you missing GNU coreutils?」で検索 #!/usr/bin/env bash set -e unset CDPATH 〜中略〜 READLINK=$(type -p greadlink readlink | head -1) [ -n "$READLINK" ] || abort "cannot find readlink - are you missing GNU coreutils?" 〜以下略〜 [User@PC] ~ %
エラーの箇所を発見、怪しい箇所としてはここのhead。
headの確認
ここでずっこけた。buildした覚えはなかったがどうやら指が勝手に動いていたらしい。
[User@PC] ~ % head 2017/12/23 14:16:31 Status: 200 OK 2017/12/23 14:16:31 Headers: map[Date:[Sat, 23 Dec 2017 05:16:31 GMT] Content-Length:[54] Content-Type:[text/html; charset=utf-8] Set-Cookie:[VISIT=TRUE]] [User@PC] ~ % which head /path/to/$GOPATH/bin/head [User@PC] ~ %
ひとまず/path/to/$GOPATH/bin/headを削除して動作を確認。
[User@PC] ~ % rm -f $GOPATH/bin/head [User@PC] ~ % python Python 2.7.10 (default, Jul 15 2017, 17:16:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ^D [User@PC] ~ %
OK.
PATHの確認
編集前提なのでvimで開いた。
[User@PC] ~ % cat .zshrc 〜中略〜 # Go env export GOROOT=$HOME/.anyenv/envs/goenv/versions/$GO_VERSION export GOPATH=$HOME/dev export PATH=$GOROOT/bin:$GOPATH/bin:$PATH 〜以下略〜 [User@PC] ~ %
ツラい。以下のように修正。
- export PATH=$GOROOT/bin:$GOPATH/bin:$PATH + export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
大切なことなので再び結論(自戒を込めて
- ビルトインのコマンド名を自作プログラムに使うのはNG(大昔から言われてるからそれ
- 自作プログラムへのPATHは追加する形で(昔から(ry
ソースコードリーディング楽しい(白目してない
所感
- 今まで事故らなかった不思議に困惑
- トラブルシューティングよりブログを書く方が時間かかってしんどい
以上!閉廷!解散!