你正在使用的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
运行:
- flag_bug.exe -h
- "c:\temp"\flag_bug.exe -h
- "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
5条答案
按热度按时间klr1opcd1#
For some more context, this only happens with cmd.exe
"c:\temp\"flag_bug.exe -h
is invalid in powershellThe 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.
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文件。然而,情况并非如此。
kuuvgm7e3#
顺便说一下,我认识到这个bug可能不是来自flags库--根据你的评论,os.Args是
c:\temp"flag_bug.exe
,这个bug很可能就在那里。prdp8dxp4#
感谢提供的文档链接。C程序确实显示
arg[0]
为c:\temp\flag_bug.exe
。根据操作系统所有者@rsc@robpike@ianlancetaylor@bradfitz@griesemer的建议,使用ping命令。qhhrdooz5#
CC @alexbrainman