やりたいこと
- goで実行中のプログラムのpidを、
$HOME/.mytool/pids/mytool.pid
に保存したい。 - クロスコンパイル環境でも動作させたい。
pidファイルを保存するプログラム
必要なパッケージ
- pidfile: pidファイルを簡単に作成できる。
- go-homedir: クロスコンパイル環境でHOME dirを取得できる。
ソースコード
main.go
import (
"fmt"
"github.com/facebookgo/pidfile"
homedir "github.com/mitchellh/go-homedir"
)
func main() {
dir, err := homedir.Dir()
if err != nil {
fmt.Println(err.Error())
return
}
pidfilePath := fmt.Sprintf("%s/%s", dir, "/.mytool/pids/mytool.pid")
pidfile.SetPidfilePath(pidfilePath)
err = pidfile.Write()
if err != nil {
fmt.Println(err.Error())
return
}
defer func() {
err = os.Remove(pidfilePath)
if err != nil {
fmt.Println(err)
}
}()
time.Sleep(30 * time.Second)
}
実行
パッケージ管理ツールにdepを使っている場合は、以下のコマンドでインストールします。
$ dep ensure -add github.com/facebookgo/pidfile
$ dep ensure -add github.com/mitchellh/go-homedir
$ dep ensure
main.goを実行し、pidファイルを確認
$ go run main.go
# ターミナルの別タブを開く
$ cat ~/.mytool/pids/mytool.pid
8642
おまけ: プロセスをkillするプログラム
ソースコード
process_killer.go
package main
import (
"fmt"
"os"
"github.com/facebookgo/pidfile"
homedir "github.com/mitchellh/go-homedir"
)
func main() {
dir, err := homedir.Dir()
if err != nil {
fmt.Println(err.Error())
return
}
pidfilePath := fmt.Sprintf("%s/%s", dir, "/.mytool/pids/mytool.pid")
pidfile.SetPidfilePath(pidfilePath)
defer func() {
err = os.Remove(pidfilePath)
if err != nil {
fmt.Println(err)
}
}()
pid, err := pidfile.Read()
fmt.Printf("pid: %d\n", pid)
if err != nil {
fmt.Println(err.Error())
return
}
process, err := os.FindProcess(pid)
err = process.Kill()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("killed process: pid:%d\n", pid)
}
実行
$ go run main.go
# ターミナルの別タブ
$ go run process_killer.go
pid: 10211
killed process: pid:10211