0

Hello I have a command line wrapper for exec.Command function as below :

func GenCmd(cmdline string) *exec.Cmd {
    fmt.Println("command is ", cmdline)
    // splitting head => g++ parts => rest of the command
    parts := strings.Fields(cmdline)

    head := parts[0]
    parts = parts[1:len(parts)]

    // exec cmd & collect output
    cmd := exec.Command(head, parts...)
    fmt.Printf("Generated comdline : %s", cmd)
    return cmd
}

func exeCmd(cmdline string, wg *sync.WaitGroup) {
    cmd := GenCmd(cmdline)
    out, err := cmd.Output()
    if err != nil {
        fmt.Printf("%s", err)
    }
    fmt.Printf("%s", out)
    wg.Done() // signal to waitgroup this goroutine complete
}

I want to call a curl command as below in my wrapper , origin curl command as below:

curl -G https://api.github.com/search/repositories       \
    --data-urlencode "q=created:>`date -v-7d '+%Y-%m-%d'`" \
    --data-urlencode "sort=stars"                          \
    --data-urlencode "order=desc"                          \
    -H "Accept: application/vnd.github.preview"            \
    | jq ".items[0,1,2] | {name, description, language, watchers_count, html_url}"

But seems like character - ` both need to be escaped at command

`date -v-7d '+%Y-%m-%d'`

Any idead how can I do that ?

main function below:

func main() {
    x := []string{
        `curl -G https://api.github.com/search/repositories ` +
            `--data-urlencode "q=created:>\`date -v-7d '+%Y-%m-%d'\`" --data-urlencode 'sort=stars' --data-urlencode 'order=asc'` +
            `-H 'Accept: application/vnd.github.preview'` +
            `| jq ".items[0,1,2] | {name, description, language, watchers_count, html_url}"`
    }

    cmdCnt := len(x)
    wg := new(sync.WaitGroup)
    wg.Add(cmdCnt)

    for _, cmd := range x {
        go exeCmd(cmd, wg) // empty string output to stdout
    }

    wg.Wait()
}

Here is full golang code

Jia
  • 2,417
  • 1
  • 15
  • 25
  • 1
    blami's answer shows how to fix the immediate problem, but there's another problem. The program does not invoke a shell, but the command line uses several shell features: sub-command evaluation, piping and quoting. Run the command line as is in a shell. –  Jun 18 '22 at 02:52
  • @RedBlue is there a more general way of 'running shell commands' in go ? ideally just copy paste command line in Go file , then it could run as it is – Jia Jun 18 '22 at 02:56
  • 1
    Run a shell. Use the shell's -c flag to run your command line. `cmd := exec.Command("bash", "-c", "")` –  Jun 18 '22 at 03:27
  • 1
    There is no valid reason to shell out to curl to make a HTTP request in Go. – Volker Jun 18 '22 at 07:47
  • @Volker could you be more specific ? willing to learn about why, or could you provide some reference / examples for the proper way of doing what I want ? – Jia Jun 18 '22 at 09:18
  • 1
    Just make a HTTP request with net/http. – Volker Jun 18 '22 at 11:27

1 Answers1

2

You cannot escape backticks inside backticks but you can build long string like this:

`first 
 part ` + "`second part`" + `…`
blami
  • 6,588
  • 2
  • 23
  • 31