Reputation: 1015
I am calling a python script from Go code:
package main
import (
"os/exec"
"os"
"fmt"
"time"
"encoding/json"
)
func main() {
cmd := exec.Command("python","/home/devendra/Desktop/sync/blur_multithread.py","http://4.imimg.com/data4/TP/ED/NSDMERP-28759633/audiovideojocks.png")
var logs=make(map[string]interface{})
logs["tes"]=os.Stdout
_ = cmd.Run()
WriteLogs(logs)//Writelog is my function which logs everything in a file
}
func WriteLogs(logs map[string]interface{}){
currentTime := time.Now().Local()
jsonLog, err := json.Marshal(logs)
if err != nil {
fmt.Println(err.Error())
}
jsonLogString := string(jsonLog[:len(jsonLog)])
logfile := "/home/devendra/ImageServiceLogs/"+ "ImageServiceLogs_" + currentTime.Format("2006-01-02") + ".txt"
if logfile == "" {
fmt.Println("Could not find logfile in configuration ...!!!")
} else {
jsonLogFile, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
defer jsonLogFile.Close()
if err != nil {
fmt.Println(err.Error())
}
jsonLogFile.WriteString(jsonLogString + "\n")
}
}
But in the logs value of tes field is null while my python script is giving me output. How to get the output of python script in my code?
Upvotes: 1
Views: 4226
Reputation:
As per official documentation examples, exec.Cmd.Ouput() ([]byte, error)
will give you the sdout of the command after it has finished running.
https://golang.org/pkg/os/exec/#Cmd.Output
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("date").Output()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)
}
To receive both stdout and stderr of the process, writer should use exec.Cmd.CombinedOutput
https://golang.org/pkg/os/exec/#Cmd.CombinedOutput
If someone wants to receive the command output in real time to its terminal, then the writer should set exec.Cmd.Stdout
and exec.Cmd.Stderr
properties to, respectively, os.Stdout
and os.Stderr
and invoke the exec.Cmd.Run() error
method.
https://golang.org/pkg/os/exec/#Cmd https://golang.org/pkg/os/exec/#Cmd.Run
package main
import (
"fmt"
"log"
"os"
"os/exec"
)
func main() {
cmd := exec.Command("date")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)
}
To forward outputs and capture it at the same time, writer should seek help of the io
package to use an io.MultiWriter
https://golang.org/pkg/io/#MultiWriter
package main
import (
"fmt"
"io"
"log"
"os"
"os/exec"
)
func main() {
stdout := new(bytes.Bufer)
stderr := new(bytes.Bufer)
cmd := exec.Command("date")
cmd.Stdout = io.MultiWriter(os.Stdout, stdout)
cmd.Stderr = io.MultiWriter(os.Stderr, stderr)
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)
}
Alternatively, you can make use of the exec.Cmd.{Stdout,Stderr}Pipe()
see the official documentation examples https://golang.org/pkg/os/exec/#Cmd.StdoutPipe
Upvotes: 2