I am refer to the post How to execute system command with unknown arguments? to run a jq command on my ubuntu shell. Below is the code I tried
import (
"fmt"
"os/exec"
"sync"
"strings"
)
func exeCmd(cmd string, wg *sync.WaitGroup) {
fmt.Println("command is ",cmd)
// splitting head => g parts => rest of the command
parts := strings.Fields(cmd)
head := parts[0]
parts = parts[1:len(parts)]
out, err := exec.Command(head,parts...).Output()
if err != nil {
fmt.Printf("%s", err)
}
fmt.Printf("%s", out)
wg.Done() // Need to signal to waitgroup that this goroutine is done
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(1)
x := []string{"jq '(.data.legacyCollection.collectionsPage.stream.edges|map({node:(.node|{url,firstPublished,headline:{default:.headline.default},summary})})) as $edges|{data:{legacyCollection:{collectionsPage:{stream:{$edges}}}}}' long-response.json > short-response.json"}
exeCmd(x[0], wg)
wg.Wait()
}
The output is as below, seems like the commans is correctly detected but shell returns exit status 3 which is "no such process" ?
command is jq '(.data.legacyCollection.collectionsPage.stream.edges|map({node:(.node|{url,firstPublished,headline:{default:.headline.default},summary})})) as $edges|{data:{legacyCollection:{collectionsPage:{stream:{$edges}}}}}' long-response.json > short-repsonse.json exit status 3
Anyone can help on this ? What I want is a go function that can wrapper and run bash command line the same way as I do on Linux shell PS: the jq command I tried above works pretty well when I paste it on my Linux shell
Tried somethine else: deleted the single quote in my jq command and my command got executed with output I expect - a parsed json file but still, I got a exist status 2 , anyone can explain
- why the single quote in my command line affects how G parse the command ?
- why I still go exist 2 after my shell commands complete?
CodePudding user response:
The program executes the jq command, not a shell. The jq command does not understand the shell syntax passed to the command (the quotes and I/O redirection).
Use the following code to run the command with stdout redirected to short-response.json.
cmd := exec.Command("jq",
"(.data.legacyCollection.collectionsPage.stream.edges|map({node:(.node|{url,firstPublished,headline:{default:.headline.default},summary})})) as $edges|{data:{legacyCollection:{collectionsPage:{stream:{$edges}}}}}",
"long-response.json")
f, err := os.Create("short-response.json")
if err != nil {
log.Fatal(err)
}
defer f.Close()
cmd.Stdout = f // set stdout to short-response.json
err = cmd.Run()
if err != nil {
log.Fatal(err)
}