go flag:无法解析在可执行路径内特别放置(但有效)双引号的标志

ddrv8njm  于 6个月前  发布在  Go
关注(0)|答案(5)|浏览(75)

你正在使用的Go版本是(go version):go version go1.15.2 darwin/amd64, cross-compiling for and running on win
在为win交叉编译后,然后在win上运行时,我注意到了这个问题。我只能在Win上重现这个问题。我没有尝试在win上本地编译,看看在那些情况下这个问题是否也存在

这个问题在最新版本的发布中是否会重现?

你正在使用的操作系统和处理器架构是什么(go env)?
主机(构建):
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/mattewong/Library/Caches/go-build"
GOENV="/Users/mattewong/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/mattewong/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/mattewong/go"
GOPRIVATE=""
GOPROXY=" https://proxy.golang.org,direct "
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/3d/4_23s9qj7dj3z966y7_q__hm0000gp/T/go-build380736401=/tmp/go-build -gno-record-gcc-switches -fno-common"
目标(运行):Windows Server 2016

你做了什么?
flag_bug.go:

/*
  demo of flag bug
*/
package main

import (
        "flag"
        "log"
)

func main() {
        stringVar := "default string value"
        flag.StringVar(&stringVar, "str", stringVar, "set a string var")
        flag.Parse()
        log.Printf("String var: %s\n", stringVar)
}

编译:
GOOS=windows go build flag_bug.go
将flag_bug.exe复制到目标系统c:\temp
运行:

  1. flag_bug.exe -h
  2. "c:\temp"\flag_bug.exe -h
  3. "c:\temp"flag_bug.exe -h

你期望看到什么?
每次都是相同的结果:usage
但实际上看到的是:

Usage of flag_bug.exe:
  -str string
        set a string var (default "default string value")

前两个行为预期:

2020/12/07 20:10:22 String var: default string value
klr1opcd

klr1opcd1#

For some more context, this only happens with cmd.exe
"c:\temp\"flag_bug.exe -h is invalid in powershell
The terminal interprets \" to mean a literal " so the quoting is technically invalid.
os.Args reports args as [c:\temp"flag_bug.exe -h]
So there might be something fixable in Go but I'm not sure if that would happen.

inb24sb2

inb24sb22#

终端解释“”为字面意义上的引号,因此引用在技术上是无效的。
我不认为这个说法是正确的。它可能在powershell中是正确的,但在cmd.exe中绝对不正确,因为cmd.exe可以找到并执行二进制文件。如果它是正确的,那么操作系统会寻找名为temp"flag_bug.exe的文件,该文件位于C:中,并且会因找不到文件而报错。
我认为这种行为在https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?redirectedfrom=MSDN&view=msvc-160中有记录(我加了强调):
The first argument (argv[0]) is treated specially. It represents the program name. Because it must be a valid pathname, parts surrounded by double quote marks (") are allowed. The double quote marks aren't included in the argv[0] output. The parts surrounded by double quote marks prevent interpretation of a space or tab character as the end of the argument. **The later rules in this list don't apply.**
只有在一个“后续规则”中,即明确不适用于argv[0]的情况下,才会说:“前导反斜杠(")后的双引号被解释为字面意义上的双引号(”)”。
即使这是一个已知的问题,不会被修复,我也必须不同意这个建议,认为这不是一个bug。“我的程序正在运行,但无法找到我传递给它的标志”是一个bug,无论存在什么技术原因。如果Windows本身按照你建议的方式解释它,那么Windows就无法找到并执行exe文件。然而,情况并非如此。

kuuvgm7e

kuuvgm7e3#

顺便说一下,我认识到这个bug可能不是来自flags库--根据你的评论,os.Args是c:\temp"flag_bug.exe,这个bug很可能就在那里。

prdp8dxp

prdp8dxp4#

感谢提供的文档链接。C程序确实显示arg[0]c:\temp\flag_bug.exe。根据操作系统所有者@rsc@robpike@ianlancetaylor@bradfitz@griesemer的建议,使用ping命令。

相关问题