我想每隔一分钟在Bash shell中运行一个命令,并在http://localhost:8080/feed上通过http提供输出

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := `<a piped command>`
    out, err := exec.Command("bash", "-c", cmd).Output()
    if err != nil {
        fmt.Sprintf("Failed to execute command: %s", cmd)
    }
    fmt.Println(string(out))
}

更新:
package main

import (
    "fmt"
    "log"
    "net/http"
    "os/exec"
)

func handler(w http.ResponseWriter, r *http.Request) {
    cmd := `<a piped command>`
    out, err := exec.Command("bash", "-c", cmd).Output()
    if err != nil {
        fmt.Sprintf("Failed to execute command: %s", cmd)
    }
    fmt.Fprintf(w, string(out))
}

func main() {
    http.HandleFunc("/feed", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

使用上面的代码,每次访问http://localhost:8080/feed时都会运行该命令。如何使它对命令的输出进行缓存(?)一分钟,然后仅在缓存时间到期后再次运行该命令?

最佳答案

如果输出不是太大,则可以将其保留在内存变量中。
在执行脚本(使用互斥锁)的情况下,我采取了等待结果的方法:

package main

import (
  "fmt"
  "net/http"
  "os/exec"
  "sync"
  "time"
)

var LoopDelay = 60*time.Second

type Output struct {
  sync.Mutex
  content string
}


func main() {

  var output *Output = new(Output)

  go updateResult(output)

  http.HandleFunc("/feed", initHandle(output))
  err := http.ListenAndServe(":8080", nil)
  if err != nil {
    fmt.Println("ERROR", err)
  }
}

func initHandle(output *Output) func(http.ResponseWriter, *http.Request) {
  return func(respw http.ResponseWriter, req *http.Request) {
    output.Lock()
    defer output.Unlock()
    _, err := respw.Write([]byte(output.content))
    if err != nil {
        fmt.Println("ERROR: Unable to write response: ", err)
    }
  }
}

func updateResult(output *Output) {
  var execFn = func() { /* Extracted so that 'defer' executes at the end of loop iteration */
    output.Lock()
    defer output.Unlock()
    command := exec.Command("bash", "-c", "date | nl ")
    output1, err := command.CombinedOutput()
    if err != nil {
      output.content = err.Error()
    } else {
      output.content = string(output1)
    }

  }
  for {
    execFn()
    time.Sleep(LoopDelay)
  }
}

执行中
date; curl http://localhost:8080/feed

提供输出(多次调用):
 1  dimanche 13 octobre 2019, 09:41:40 (UTC+0200)
http-server-cmd-output> date; curl http://localhost:8080/feed

dimanche 13 octobre 2019, 09:42:05 (UTC+0200)
 1  dimanche 13 octobre 2019, 09:41:40 (UTC+0200)

几件事要考虑:
-使用日期nl'作为带有管道示例的命令
-如果输出太大,则写入文件
-很可能只对内容更新保留互斥(在脚本执行期间无需等待)-您可以尝试改进它
-Go例程可能具有变量( channel )以在信号上退出(例如:程序结束时)

编辑:变量移至主函数

关于go - 每1分钟执行一次exec命令,并通过http提供输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58361020/

10-09 08:28
查看更多