2017-06-20 98 views
-5

我想守護myapp,但我有一個大問題。我使用的頻道類型爲chan struct{}。 但是,使用包getopt(標誌包)時,我的標誌是* bool類型的,所以我不知道如何修改myapp。從非chan類型接收*布爾

通道類型bool不夠用。我確信有一個我不明白的概念。我附上你的代碼:

package main 

import (
    "os" 
    "syscall" 
    "time" 

    "github.com/pborman/getopt/v2" 
    "github.com/sevlyar/go-daemon" 
) 

var (
    done = make(chan struct{}) 
    optQuit = make(chan struct{}) 
    optRun = make(chan struct{}) 
) 

func TermHandler(sig os.Signal) error { 
    optQuit <- struct{}{} 
    if sig == syscall.SIGQUIT { 
     <-done 
    } 
    return nil 
} 

func main() { 
    optHelp := getopt.BoolLong("help", 'h', "Help") 
    optQuit := getopt.BoolLong("quit", 0, "Help") 
    optRun := getopt.BoolLong("run", 'r', "Help") 

    if *optHelp { 
     getopt.Usage() 
     os.Exit(0) 
    } 

    // Create pid file 
    cntxt := &daemon.Context{ 
     PidFileName: "/var/run/myapp.pid", 
     PidFilePerm: 0644, 
     WorkDir:  "./", 
     Umask:  027, 
     Args:  []string{"[Z]"}, 
    } 

    if len(daemon.ActiveFlags()) > 0 { 
     d, _ := cntxt.Search() 
     daemon.SendCommands(d) 
     return 
    } 
    d, err := cntxt.Reborn() 
    if d != nil { 
     return 
    } 
    if err != nil { 
     os.Exit(1) 
    } 
    defer cntxt.Release() 

    // Define ticker 
    ticker := time.NewTicker(time.Second) 
    myapp := true 

    // Loop 
    for myapp { 
     select { 

     // Case sleep 
     case <- ticker.C: 
      time.Sleep(time.Second) 

     // Case QUIT 
     case <- optQuit: 
      done <- struct{}{} 
      myapp = false 
      ticker.Stop() 
      os.Exit(0) 

     // Case RUN 
     case <- optRun: 
      // Executes a goroutine... 
     } 
    } 
} 

隨着go install,我可以看到這個錯誤:

./main.go:72: invalid operation: <-optQuit (receive from non-chan type *bool) 
./main.go:79: invalid operation: <-optRun (receive from non-chan type *bool) 

我不知道我應該怎麼修改通道(做,類型結構的optQuit {}) ,解決這個問題...

PS:我給你看一個我做的例子。它作爲守護進程運行,每分鐘執行Writer()函數。 之後,如果您輸入zdaemon -z quit,應用程序會正常關機。你可以在你的機器上運行它:

https://play.golang.org/p/RVq7M7usEj

+0

似乎有點題外話這裏,也許嘗試爲:https://codereview.stackexchange。 com/ – Krom

回答

0

這兩行中的主要功能影子你的全局變量聲明:

optQuit := getopt.BoolLong("quit", 0, "Help") 
optRun := getopt.BoolLong("run", 'r', "Help") 

如果你只使用它們,得到一個不錯的用法,爲什麼你自己沒有創建一個使用函數 ?

如果你堅持要用getopt只是爲了創造一個用法,做

_ = getopt.BoolLong("quit", 0, "Help") 
_ = getopt.BoolLong("run", 'r', "Help") 

代替。

您還需要在使用*optHelp之前致電getopt.Parse()

所得消息

Usage: test [-hr] [--quit] [parameters ...] 
-h, --help Help 
    --quit Help 
-r, --run Help 

似乎是小於有幫助的。爲什麼不只是做

fmt.Printf(` 
Usage: test 
    This program will start a daemon service, which you can use like this ... 
`) 
+0

這是我想要做的,我以爲我必須使用getopt.BoolLong的返回來在選擇函數中使用它...謝謝! – icarbajo

0

您全局定義optQuit = make(chan struct{}),然後在主遮蓋了:optQuit := getopt.BoolLong("quit", 0, "Help")

所以在主optQuit是bool,不是chan

在主刪除這兩條線:

optQuit := getopt.BoolLong("quit", 0, "Help") 
optRun := getopt.BoolLong("run", 'r', "Help") 
+0

我明白你的解決方案,但我使用這個軟件包來獲取幫助菜單...這是一個問題,我如何能夠適應所有? – icarbajo

+0

我不確定你想要做什麼。打印幫助'optQuit'?然後只要有人給出參數'h'就打印一個字符串。不要濫用軟件包並殺死你的程序。 – RickyA