这是什么原因导致了这种golang os.Exec行为(转义双引号)?

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

What causes this golang os.Exec behavior (escaped double quotes)?

问题

我有以下代码:

for i := 0; i < 1; i++ {
    wait := rand.Int63n(150) + 300
    time.Sleep(time.Millisecond * time.Duration(wait))
    //
    useragent := "--user-agent='Mozilla/5.0 (X11; CrOS armv7l 8872.76.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.105 Safari/537.36'"
    outDirectory := "--output-document=temp/review-" + strconv.Itoa(i) + ".html"
    header := "--header=\"Content-Type: application/x-www-form-urlencoded;charset=utf-8\""
    uri := "https://play.google.com/store/getreviews"
    payload := "--post-data=id=fi.danskebank.mobilepay&reviewSortOrder=2&xhr=1&reviewType=0&pageNum=" + strconv.Itoa(i)
    cmd := exec.Command("wget", useragent, outDirectory, header, uri, payload)
    fmt.Println(strings.Join(cmd.Args, " "))
    bytes, _ := cmd.CombinedOutput()
    fmt.Println(string(bytes))
}
fmt.Println("Finished crawling")

如果我将 payload 行从

payload := "--post-data=id=fi.danskebank.mobilepay&reviewSortOrder=2&xhr=1&reviewType=0&pageNum=" + strconv.Itoa(i)

改为

payload := "--post-data=\"id=fi.danskebank.mobilepay&reviewSortOrder=2&xhr=1&reviewType=0&pageNum=" + strconv.Itoa(i) + "\""

它会返回 Server Error 500,即使在运行相应的 wget 命令时:

wget --user-agent='Mozilla/5.0 (X11; CrOS armv7l 8872.76.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.105 Safari/537.36' --output-document=temp/review-0.html --header="Content-Type: application/x-www-form-urlencoded;charset=utf-8" https://play.google.com/store/getreviews --post-data="id=fi.danskebank.mobilepay&reviewSortOrder=2&xhr=1&reviewType=0&pageNum=0"

它将与未转义引号的 post-data 产生相同的响应。

为什么 Golang 的 os.Exec 会导致这种行为?

英文:

I have the following code:

for i := 0; i &lt; 1; i++ {
	wait := rand.Int63n(150) + 300
	time.Sleep(time.Millisecond * time.Duration(wait))
	//
	useragent := &quot;--user-agent=&#39;Mozilla/5.0 (X11; CrOS armv7l 8872.76.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.105 Safari/537.36&#39;&quot;
	outDirectory := &quot;--output-document=temp/review-&quot; + strconv.Itoa(i) + &quot;.html&quot;
	header := &quot;--header=\&quot;Content-Type: application/x-www-form-urlencoded;charset=utf-8\&quot;&quot;
	uri := &quot;https://play.google.com/store/getreviews&quot;
	payload := &quot;--post-data=id=fi.danskebank.mobilepay&amp;reviewSortOrder=2&amp;xhr=1&amp;reviewType=0&amp;pageNum=&quot; + strconv.Itoa(i)
	cmd := exec.Command(&quot;wget&quot;, useragent, outDirectory, header, uri, payload)
	fmt.Println(strings.Join(cmd.Args, &quot; &quot;))
	bytes, _ := cmd.CombinedOutput()
	fmt.Println(string(bytes))
}
fmt.Println(&quot;Finished crawling&quot;)

If I change the payload line from

payload := &quot;--post-data=id=fi.danskebank.mobilepay&amp;reviewSortOrder=2&amp;xhr=1&amp;reviewType=0&amp;pageNum=&quot; + strconv.Itoa(i)

to

payload := &quot;--post-data=\&quot;id=fi.danskebank.mobilepay&amp;reviewSortOrder=2&amp;xhr=1&amp;reviewType=0&amp;pageNum=&quot; + strconv.Itoa(i) + &quot;\&quot;&quot;

It will return Server Error 500, even though when running the corresponding wget:

wget --user-agent=&#39;Mozilla/5.0 (X11; CrOS armv7l 8872.76.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.105 Safari/537.36&#39; --output-document=temp/review-0.html --header=&quot;Content-Type: application/x-www-form-urlencoded;charset=utf-8&quot; https://play.google.com/store/getreviews --post-data=&quot;id=fi.danskebank.mobilepay&amp;reviewSortOrder=2&amp;xhr=1&amp;reviewType=0&amp;pageNum=0&quot;

It will have same response as the post-data without escaped quotes.

Why does Golang os.Exec result in this behavior?

答案1

得分: 3

当你在shell中执行命令时,shell会处理引号,但它们不会传递给你要执行的程序。当你在Go中执行命令时,不涉及shell处理,所以引号会被传递。由于程序不期望引号,它们会直接传递到请求体中,服务器会返回错误。

与你的问题无关,但如果你没有特定的原因使用wget,使用内置的HTTP客户端比每个请求都fork到wget要获得更好的性能。

英文:

When you execute the command in your shell, the shell processes the quotes and they aren't passed to the program you're executing. When you execute a command in Go, there is no shell processing involved, so the quotes are passed through. Since the program isn't expecting them, they get passed through directly in the request body, and the server responds with an error.

Unrelated to your issue, but if you don't have a specific reason to use wget, you'd get far better performance using the built-in HTTP client than forking out to wget for every request.

huangapple
  • 本文由 发表于 2017年9月6日 23:05:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/46078685.html
匿名

发表评论

匿名网友

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

确定