从非陈类型*布尔接收

I want to daemonize myapp but I have one big problem. The channels I'm using are of type chan struct{}. However, with the package getopt (flag package), my flags are of type *bool, so I don't know how can I modify myapp.

It's not enough with channels type bool. I'm sure there are a concept that I don't understand. I attach you the code:

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...
        }
    }
}

With go install, I can see this errors:

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

I don't know how I should modify the channels (done, optQuit of type struct{}), to resolve this...

P.S.: I show you an example that I did. It runs as daemon and each minute, it executes the function Writer(). After, if you type zdaemon -z quit, the app does a graceful shutdown. You can run it in your machines:

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

Those two lines in your main function shadow your global variable declaration:

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

If you only use them, to get a nice usage, why not create a usage function yourself?

If you insist on using getopt just to create a usage, do

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

instead.

You also need to call getopt.Parse() before using *optHelp.

The resulting message

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

seems to be less than helpful. Why not just do

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

You define optQuit = make(chan struct{}) globally and then shadow it in main: optQuit := getopt.BoolLong("quit", 0, "Help").

So in main optQuit is a bool, not a chan

Remove those two lines in main:

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