Executing command with spaces in one of the parts

前端 未结 2 1669
囚心锁ツ
囚心锁ツ 2021-01-23 20:04

I am running a command through the os/exec package that is called like this:

out, err := Exec(\"ffprobe -i \'/media/Name of File.mp3\' -show_entries format=dura         


        
2条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-23 20:45

    1. You may use strings.Split(s, ":") on special character like : and switch " with back-tick,
      Like this working sample (The Go Playground):
    package main
    
    import (
        "fmt"
        "strings"
    )
    
    func main() {
        command := `ffprobe : -i "/media/Name of File.mp3" : -show_entries format=duration : -v quiet : -of csv=p=0`
        parts := strings.Split(command, ":")
        for i := 0; i < len(parts); i++ {
            fmt.Println(strings.Trim(parts[i], " "))
        }
    }
    

    output:

    ffprobe
    -i "/media/Name of File.mp3"
    -show_entries format=duration
    -v quiet
    -of csv=p=0
    
    1. try print cmd.Args after cmd := exec.Command("ffprobe", s...) (remove .Output() ):

      for _, v := range cmd.Args { fmt.Println(v) }

    something like this, to find out what happens to your args:

    s := []string{"-i '/media/Name of File.mp3'", "-show_entries format=duration", "-v quiet", "-of csv=p=0"}
    cmd := exec.Command("ffprobe", s...)
    
    for _, v := range cmd.Args {
        fmt.Println(v)
    }
    cmd.Args = []string{"ffprobe", "-i '/media/Name of File.mp3'", "-show_entries format=duration", "-v quiet", "-of csv=p=0"}
    fmt.Println()
    for _, v := range cmd.Args {
        fmt.Println(v)
    }
    

    see:

    // Command returns the Cmd struct to execute the named program with
    // the given arguments.
    //
    // It sets only the Path and Args in the returned structure.
    //
    // If name contains no path separators, Command uses LookPath to
    // resolve the path to a complete name if possible. Otherwise it uses
    // name directly.
    //
    // The returned Cmd's Args field is constructed from the command name
    // followed by the elements of arg, so arg should not include the
    // command name itself. For example, Command("echo", "hello")
    func Command(name string, arg ...string) *Cmd {
        cmd := &Cmd{
            Path: name,
            Args: append([]string{name}, arg...),
        }
        if filepath.Base(name) == name {
            if lp, err := LookPath(name); err != nil {
                cmd.lookPathErr = err
            } else {
                cmd.Path = lp
            }
        }
        return cmd
    }
    

    Edit 3- Try this

    package main
    
    import (
        "fmt"
        "os/exec"
    )
    
    func main() {
    
        cmd := exec.Command(`ffprobe`, `-i "/media/Name of File.mp3"`, `-show_entries format=duration`, `-v quiet`, `-of csv=p=0`)
        for _, v := range cmd.Args {
            fmt.Println(v)
        }
        fmt.Println(cmd.Run())
    }
    

提交回复
热议问题