【问题标题】:How to run this command via Go?如何通过 Go 运行此命令?
【发布时间】:2020-07-21 12:20:39
【问题描述】:
echo "test_metric:20|c" | nc -v -C -w 1 host.address port

我通过终端运行这个命令,我得到了想要的结果。但是我怎样才能通过 Go 代码做同样的事情呢?

经过这里的回答后,我尝试了这个-

sh:= os.Getenv("SHELL")
cmd := exec.Command(sh, "-c ", `echo "test_metric:20|c" | nc -v -C -w 1 host.address port`)

cmd.Stdout = os.Stdout

cmd.Run()

但没有运气。

【问题讨论】:

  • -c 参数后有一个尾随空格。如果修复此问题不能解决您的问题,请将 Stderr 输出添加到问题中。
  • @Samik :如果未定义环境变量SHELL,或者将其设置为不理解命令语法或-c 选项的某个shell,您的方法将失败。如果您为 POSIX shell 编写此代码,只需使用文字 sh 并让调用者负责确保 sh 在 PATH 中。

标签: shell go command


【解决方案1】:

我没有看到调用 shell 来执行此操作的意义:

package main

import (
    "bytes"
    "flag"
    "fmt"
    "io"
    "log"
    "net"
    "time"
)

var (
    host    string
    port    int
    timeout string
)

func init() {
    flag.StringVar(&host, "host", "localhost", "host to connect to")
    flag.IntVar(&port, "port", 10000, "port to connect to")
    flag.StringVar(&timeout, "timeout", "1s", "timeout for connection")
}

func main() {
    flag.Parse()

    // Fail early on nonsensical input.
    if port < 1 || port > 65535 {
        log.Fatalf("Illegal port %d: must be >=1 and <=65535", port)
    }

    var (
        // The timeout for the connection including name resolution
        to time.Duration

        // The ubiquitous err
        err error

        // The dial string
        addr = fmt.Sprintf("%s:%d", host, port)

        // The actual connection
        con net.Conn

        // Your playload. It should be easy enough to make this
        // non-static.
        payload = []byte("test_metric:20|c")
    )

    // Check the user has given a proper timeout.
    if to, err = time.ParseDuration(timeout); err != nil {
        log.Fatalf("parsing timeout: %s", err)
    }

    // You might want to implement a retry strategy here.
    // See https://stackoverflow.com/a/62909111/1296707 for details
    if con, err = net.DialTimeout("tcp", addr, to); err != nil {
        log.Fatalf("Error while dialing: %s", err)
    }
    defer con.Close()

    // This simulates about every input.
    // You can use a pipe of a command or whatever you want.
    dummyReader := bytes.NewBuffer(payload)

    if w, err := io.Copy(con, dummyReader); err != nil && w < int64(len(payload)) {
        log.Printf("Short write: written (%d) < payload (%d): %s", w, len(payload), err)
    } else if err != nil {
        // This should not happen, as usually an error is accompanied by a short write
        log.Println("Uuupsie!")
    }

}

在一个 shell 上启动一个 netcat 监听器:

$ nc -k -l 10000

通过

运行代码
$ go run dacode.go

您应该会在 netcat 侦听器的输出中看到您的有效负载。

如果您想将程序的输出传输到远程服务器,只需通过os.Exec 调用相应的命令,并在con 上使用io.Copy 和您的命令的StdoutPipe() 返回的io.Reader

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2013-06-05
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多