我正在尝试在Go中运行以下代码。我尝试了以下两种方法:
out, err := exec.Command("sh", "-c", "tcpdump -i ens0 host 192.168.1.100 -F ./testfile").Output()
fmt.Println(string(out)) // Prints nothing
fmt.Println(err) // exit status 1
我还尝试过将sh
替换为/bin/bash
。
我还尝试了以下操作,并在第一个参数不使用sh
的情况下进行了
out, err := exec.Command("tcpdump", "-i", "ens0", "host", "192.168.1.100", "-F", "./testfile").Output()
fmt.Println(string(out)) // Prints nothing
fmt.Println(err) // exit status 1
所有这些都不起作用。有人可以看到我在做什么吗?我也尝试过使用go软件包"github.com/kami-zh/go-capturer"
来读取stderr并再次不输出任何内容。
通常我必须使用sudo
从外壳执行tcpdump
,所以我构建了go二进制文件并以root用户身份执行。
答案 0 :(得分:0)
类似的东西应该可以工作,我不确定tcp dump中是否有任何特定的命令,例如-F,
如果要捕获tcp转储的普通输出,则可以使用> file
将输出定向到文件。 -w选项用于wireshark / tcpdump格式,以读取和显示
cmd := exec.Command("sh", "-c", "sudo tcpdump -i <eth> host <ip> -w ./testfile")
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
感谢@ torek,-c选项可与tcpdump一起使用,以在捕获n个数据包后退出
cmd := exec.Command("sh", "-c", "sudo tcpdump -i ens33 -c 100 host localhost -w ./testfile")
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
另一种方法是使用cmd.Start
cmd := exec.Command("sh", "-c", "sudo tcpdump -i ens33 -c 100 host localhost -w ./testfile")
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
log.Printf("Waiting for command to finish...")
err = cmd.Wait()
log.Printf("Command finished with error: %v", err)
如果在tcpdump cmd中使用不带-c选项的cmd.run,则tcpdump命令将继续无限运行,因此您看不到是否在cmd.Run()调用后放置了print语句,原因是exec.Command失败的是,它与cli的工作方式相同,因此,如果需要它在sodo的前面,则也应将其放在命令中或从root用户运行。