如何将包含任意字符的 Golang 变量传递给 Linux 中的 echo 二进制文件?

huangapple go评论88阅读模式
英文:

How to pass a golang variables( can contain any character) to echo binary in linux?

问题

我的代码看起来像这样,我定义了一个函数如下:

func shellOut(command string) (string, string, error) {
    var stdout bytes.Buffer
    var stderr bytes.Buffer
    cmd := exec.Command("bash", "-c", command)
    cmd.Stdout = &stdout
    cmd.Stderr = &stderr
    err := cmd.Run()
    return stdout.String(), stderr.String(), err
}

然后稍后我这样做。

t := "yoooooooooooo\"oo)(';#oooooooooooo"
out, stderr, err := shellOut("echo \"" + t + "\"  | ./doOperation.sh")
if err != nil {
    log.Printf("final error: %v\nstderr: %s", err, stderr)
}   
fmt.Println(out)

但是我得到了以下错误:

2021/10/14 22:54:18 final error: exit status 1
stderr: bash: -c: line 838: syntax error near unexpected token `('
bash: -c: line 838: `                return "Symbol(" + String(void 0 === t ? "" : t) + ")_" + (++n + r).toString(36)';

当我给变量t赋一个值,比如"yooooo"时,它可以正常执行。那么我如何传递一个带有任何奇怪字符的变量到echo命令中?有没有一种方法在传递之前转义所有不良字符?

英文:

so my code looks like this , i have a function defined as the following :

func shellOut(command string) (string, string, error) {
    var stdout bytes.Buffer
    var stderr bytes.Buffer
    cmd := exec.Command("bash", "-c", command)
    cmd.Stdout = &stdout
    cmd.Stderr = &stderr
    err := cmd.Run()
    return stdout.String(), stderr.String(), err
}

and a while later i am doing this.

  t := "yoooooooooooo\"oo)(';#oooooooooooo"
    out, stderr, err := shellOut("echo \"" + t + "\"  | ./doOperation.sh")
    if err != nil {
        log.Printf("final error: %v\nstderr: %s", err, stderr)
    }   
    fmt.Println(out)

but i am getting an error that looks like this:

2021/10/14 22:54:18 final error: exit status 1
stderr: bash: -c: line 838: syntax error near unexpected token `('
bash: -c: line 838: `                return "Symbol(" + String(void 0 === t ? "" : t) + ")_" + (++n + r).toString(36)'

and when i give the variable t a value like "yooooo" its gets executed nicely, so how can i pass a variable with any weird character into echo? is there a way to escape all bad character before passing it?

答案1

得分: 1

纯粹出于学术目的,我发布了这个函数,因为我之前不久也做过类似的事情:

var bashReplacer = strings.NewReplacer(
    `)`, `\)`,
    `(`, `\(`,
    `'`, `\'`,
    `"`, `\"`,
    `$`, `$`,
    "`", "\\`",
)

func bashEscape(s string) string { return bashReplacer.Replace(s) }

然而,正如我在评论中提到的,你可以通过直接运行目标脚本并将UTF-8字符串原样传入来避免所有的shell转义痛苦,方法如下:

func execWithStdin(command, stdinText string) (string, string, error) {
    var (
        stdout bytes.Buffer
        stderr bytes.Buffer
    )

    cmd := exec.Command(command)
    cmd.Stdin = strings.NewReader(stdinText) // 通过Stdin传入数据
    cmd.Stdout = &stdout
    cmd.Stderr = &stderr
    err := cmd.Run()
    return stdout.String(), stderr.String(), err
}

使用方法:

t := `yoooooooooooo"oo)(';#oooooooooooo`
t += "`" // 添加一个反引号以增加趣味性

// 无需进行shell转义:

out, stderr, err := execWithStdin("./doOperation.sh", t)

以上是要翻译的内容。

英文:

For purely academic purposes, I'm posting this function, as I had to do something similar a while back:

var bashReplacer = strings.NewReplacer(
	`)`, `\)`, // using back-ticks to keep our sanity
	`(`, `\(`,
	`'`, `\'`,
	`"`, `\"`,
	`$`, `$`, // include if you don't want variable substitutions
	"`", "\\`", // can't use back-ticks to include a back-tick, so back to double-quotes
)

func bashEscape(s string) string { return bashReplacer.Replace(s) }

https://play.golang.org/p/uNfI_2MyjcI

However, as I mentioned in the comments, you can avoid all the pain of shell escaping by just running the target script directly, and feed in your UTF-8 string unaltered like so:

func execWithStdin(command, stdinText string) (string, string, error) {
	var (
		stdout bytes.Buffer
		stderr bytes.Buffer
	)

	cmd := exec.Command(command)
	cmd.Stdin = strings.NewReader(stdinText) // pass in our data via Stdin
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	return stdout.String(), stderr.String(), err
}

to use:

t := `yoooooooooooo"oo)(';#oooooooooooo`
t += "`" // add a back-tick to make things interesting

// no shell escaping necessary:

out, stderr, err := execWithStdin("./doOperation.sh", t)

huangapple
  • 本文由 发表于 2021年10月15日 05:07:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/69577359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定