Search code examples
shellgocommand-linestdinosquery

Running a process messes up shell


I need to run a process called osqueryi before I run my app, and when shutting down, killing that process. (It is kind of a daemon which can be queried. I need it to be running in order for my app to work).

func bootOsqueryi(strcmd string) {
  cwd, err := os.Getwd()
  if err != nil {
    panic(err)
  }

  pa := os.ProcAttr{
    Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
    Dir:   cwd,
  }
  path, err := exec.LookPath(strcmd)
  if err != nil {
    handleError(err)
    return
  }
  osqueryi, err := os.StartProcess(path, []string{strcmd}, &pa)
  if err != nil {
    handleError(err)
    return
  }
  osqueryi.Wait()
}

I call this from a cobra PersistentPreRun hook like this: go bootOsqueryi("osqueryi").

In the PersistentPostRun hook I shut it just down:

func shutdown() {
  if osqueryi != nil {
    osqueryi.Kill()
  }
}

Osqueryi is like an interactive shell. It needs to be passed os.Stdin, because apparently it uses isatty. If I don't do that, it doesn't run. So I need to start this process because I need to query it but I don't need to write any input to it because the idea is to use a go module osquery-go to issue queries from my app...

I need to call it in a go routine because otherwise I can't write log output to the screen...

In any case, it kinda works well. BUT, when the app terminates, my terminal is messed up: my prompt line is missing (can't see what I type). I guess, because I am assigning it STDIN but I am never writing to it and in the meanwhile writing output to STDOUT via fmt.Println().

Is there a way to make this work?


Solution

  • You tagged osquery, so... Perhaps as an alternative, don't run osqueryi that way, it's not meant to be used like that.

    The general recommendation is to use osqueryd with the configuration as you'd like it. Or, if you really want to a single invocation of osqueryi you can invoke it with a query from the command line, outputting in json:

    osqueryi --json "select 1"
    [
      {"1":"1"}
    ]
    

    osqueryi is not really the same as osqueryd.