exec.Command error, no output to stdout or stderr - go

I am trying to get the duration of a video using ffprobe and exec.Command but I keep getting an error. However, stdout and stderr are both empty so I don't know what the problem is.
func getVideoLength(filename string) float64 {
cmd := exec.Command("ffprobe", "-i", filename, "-show_entries", "format=duration", "-v", "quiet", "-of", "csv=\"p=0\"")
fmt.Println("ffprobe", "-i", filename, "-show_entries", "format=duration", "-v", "quiet", "-of", "csv=\"p=0\"")
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println("out: " + out.String())
fmt.Println("stderr: " + stderr.String())
log.Fatal(err)
}
length, err := strconv.ParseFloat(out.String(), 64)
if err != nil {
log.Fatal(err)
}
return length
}
Here is the output I get:
ffprobe -i amelie.mp4 -show_entries format=duration -v quiet -of csv="p=0"
out:
stderr:
2019/02/18 21:04:39 exit status 1
not very helpful.
Any ideas?. Thanks.

The reason you aren't getting any clues is that you have set the command to not say anything. From the ffprobe docs
-loglevel [flags+]loglevel | -v [flags+]loglevel Set logging level and flags used by the library.
....
loglevel is a string or a number containing one of the following
values:
‘quiet, -8’ Show nothing at all; be silent.

Related

golang exec with cmd as argument does not print stdout

cmdstr := "ssh -i ....... blah blah blah" ssh to an ip and run rpm command to install rpm
cmd := exec.Command("/bin/bash", "-c", cmdstr)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println(out.String())
}
out.String() does not print anything
if I have ping command without /bin/bash it prints the out. Anyone knows why ?
cmd.Stdout captures the output of a successful command execution
cmd.Stderr captures the command output if an error occurs during execution
You could try the cmd.Output() variant and capture execution errors from Stderr using
cmdstr := "ssh -i ....... blah blah blah" // ssh to an ip and run rpm command to install rpm
cmd := exec.Command("/bin/bash", "-c", cmdstr)
var errb bytes.Buffer
cmd.Stderr = &errb
output, err := cmd.Output()
if err != nil {
fmt.Printf("error: %s", errb.String()) // capture any error output
}
fmt.Println(string(output)) // when successful

Go "exec.Command" of tcpdump not doing anything

I am attempting to run the following code in Go. I have tried both of the following ways:
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
I have also tried replacing sh with /bin/bash.
I have also tried the following, with and without sh as the first argument:
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
None of this is working. Can someone see what I am doing wrong? I have also tried this go package "github.com/kami-zh/go-capturer" to read stderr and again it prints nothing.
Normally I have to use sudo to execute tcpdump from shell, so I build the go binary and execute it as root user.
Something like this should work, i am not sure if there is any specific command like -F available in tcp dump,
If you want to capture plain output of the tcp dump , you can direct the output to file using > file . The -w option is for wireshark/tcpdump format , to read and display
cmd := exec.Command("sh", "-c", "sudo tcpdump -i <eth> host <ip> -w ./testfile")
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
Thanks, #torek, the -c option can be used with tcpdump to exit after capturing n packets
cmd := exec.Command("sh", "-c", "sudo tcpdump -i ens33 -c 100 host localhost -w ./testfile")
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
The other way is to use 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)
The tcpdump command continue to run infinitely if you use cmd.run without -c option with tcpdump cmd.So you can't see if you put print statement after cmd.Run() call, the reason being the exec.Command failed is, it just work the same way on how it works from the cli, so if you need sodo in front for it , you should put it in command as well or run it from the root user.

How to fix 'syntax error: A unknown token can’t go here' when running `exec.Command` in Go script

I am trying to run this Apple Script command with osascript in my Go script and I'm getting the error 0:1: syntax error: A unknown token can’t go here. (-2740).
This is the command that, when run in Terminal, works great!
/usr/bin/osascript -e 'on run {f, c}' -e 'tell app "Finder" to set comment of (POSIX file f as alias) to c' -e end "/Users/computerman/Desktop/testfile.png" "Hello, World"
My Go script below actually outputs the above string, and I can literally cut and paste it in Terminal and it works. However, running the Go script itself I get the aforementioned error.
Please help!
This is on MacOS 10.14.4 (18E2034). I tried replacing the fmt.Sprintf with simpler string with \"Finder"\ and have the same exact issue.
import (
"fmt"
"log"
"os"
"os/exec"
)
func main() {
filepath := "/Users/computerman/Desktop/testfile.png"
comment := "Hello, World"
onrun := "'on run {f, c}'"
command := fmt.Sprintf(`'tell app "Finder" to set comment of (POSIX file f as alias) to c' -e end "%s" "%s"`, filepath, comment)
log.Println("/usr/bin/osascript", "-e", onrun, "-e", command)
cmd := exec.Command("/usr/bin/osascript", "-e", onrun, "-e", command)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Println(err)
}
}
When I do go run main.go I get this in Terminal
2019/04/17 13:02:28 exit status 1
I expect the output of
Hello, World
And no errors. Plus, the comment field in the file to be updated with Hello, World.
Thanks to the previous comments, I discovered the answer. Here is the correct code that works. Thanks to Adrian for pointing out that you don't need the single quotes, so I removed them, and thanks to Nick for pointing out that the end flag needed to be separate from that string.
func main() {
filepath := "/Users/computerman/Desktop/testfile.png"
comment := "Hello, World"
onrun := "on run {f, c}"
command := fmt.Sprintf(`tell app "Finder" to set comment of (POSIX file f as alias) to c`)
//log.Println("/usr/bin/osascript", "-e", onrun, "-e", command)
cmd := exec.Command("/usr/bin/osascript", "-e", onrun, "-e", command, "-e", "end", filepath, comment)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Println(err)
}
}
It works!
You need to break out the -e on the end of command too and the comment, something like this. This makes the same number of parameters as in the original command hopefully.
func main() {
filepath := "/Users/computerman/Desktop/testfile.png"
comment := "Hello, World"
onrun := "'on run {f, c}'"
command := fmt.Sprintf(`'tell app "Finder" to set comment of (POSIX file f as alias) to c'`)
end := fmt.Sprintf(`end "%s")`, filepath)
log.Println("/usr/bin/osascript", "-e", onrun, "-e", command, "-e", end, comment)
cmd := exec.Command("/usr/bin/osascript", "-e", onrun, "-e", command, "-e", end, comment)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Println(err)
}
}

GPG command works in shell but not in Go exec.Command()

I am using gnupg to encrypt files with the following command:
gpg --encrypt --sign --armor -r person#email.com name_of_file
This command works fine in shell. But it fails in go program with following error :
gpg: cannot open '/dev/tty': Device not configured
Here is the Code:
func main() {
var stdout, stderr bytes.Buffer
cmd := exec.Command("/bin/sh", "-c", `gpg --encrypt --sign --armor -r person#email.com file_name.csv`)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Println(err)
}
out := stdout.String() + stderr.String()
fmt.Println(out)
}
Why am I getting this error and how can I fix it?

Golang + Avconv error (exit status 254)

I'm getting "panic: exit status 254" on the second line.
Can you spot the mistake I made here:
command := exec.Command("avprobe", "inputfile.mp4 -loglevel quiet -show_streams -frame_size -print_format -show_format -of json")
output, err := command.StdoutPipe();
if err != nil {
log.Panic(err)
}
if err := command.Run(); err != nil {
log.Panic(err)
}
json.NewDecoder(output).Decode(&struct1)
You are running the equivalent of
avprobe "inputfile.mp4 -loglevel quiet -show_streams -frame_size -print_format -show_format -of json"
I am guessing avprobe doesn't like that, try
command := exec.Command("avprobe", "inputfile.mp4", "-loglevel", ...)
You can also use exec.CombinedOutput() to get the output from avprobe and see what it says.
Package exec
func Command
func Command(name string, arg ...string) *Cmd
For example,
arg := []string{
"inputfile.mp4",
"-loglevel", "quiet",
"-show_streams",
"-frame_size",
"-print_format",
"-show_format",
"-of", "json",
}
command := exec.Command("avprobe", arg...)

Resources