在Golang中使用输入重定向对diff进行封装

时间:2018-10-25 21:45:55

标签: shell go

我正在尝试掏出类似于以下内容的东西:

diff  <(echo -e "$string1" ) <(echo -e "$string2")

在Golang中,但是我所有对exec.Command的尝试都失败了。

这是我尝试过的最幼稚的尝试(CombinedOutput暂时用于解决潜在问题):

func Diff(str1, str2 string) (string, error) {
    cmd := exec.Command("diff", sanitize(str1), sanitize(str2))
    bytes, err := cmd.CombinedOutput()
    result := string(bytes)
    if err != nil {
        switch err.(type) {
        case *exec.ExitError:
            return result, nil
        default:
            return "", nil
        }
    }
    return result, nil
}

哪个给了我以下结果:diff: \"foo\nbar\nbaz\": No such file or directory diff: \"foo\nfighters\nbaz\": No such file or directory

涉及程度更高的版本仍然无法使用:

func Diff(str1, str2 string) (string, error) {
    cmd := exec.Command("diff")
    stdin, err := cmd.StdinPipe()
    if err != nil {
        return "", err
    }
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        return "", err
    }
    err = cmd.Start()
    if err != nil {
        return "", err
    }
    io.WriteString(stdin, echoString(str1))
    io.WriteString(stdin, echoString(str2))
    bytes, err := ioutil.ReadAll(stdout)
    cmd.Wait()
    result := string(bytes)
    if err != nil {
        switch err.(type) {
        case *exec.ExitError:
            return result, nil
        default:
            return "", nil
        }
    }
    return result, nil
}

func echoString(str string) string {
    return fmt.Sprintf(`<( echo -e "%s" )`, strings.Replace(str, `"`, `\"`, -1))
}

根本没有输出,我在diff: missing operand after `diff' diff: Try `diff --help' for more information.中得到了stderr

因此,我认为我真的不需要echo指令,因为我已经有了字符串,因此我尝试仅用转义部分(即echoString)来代替return strings.Replace(str, `"`, `\"`, -1)实现,但是我得到相同的错误。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

这是最简单的解决方案,只需将diff命令传递到bash shell:

    cmd := exec.Command(
        "bash", "-c", 
        fmt.Sprintf("diff <(echo -e %s) <(echo -e %s)", str1, str2))