英文:
"rune literal not terminated" error when attempting to run gofmt -r with exec.Command
问题
在以下目录结构中,
.
├── foo.go
├── go.mod
└── main.go
我有一个包含简单类型定义的 foo.go 文件:
package main
type Foo struct {
Baz string
}
如果我从命令行运行 gofmt -r 来替换变量名,它可以正常工作:
> gofmt -r 'Foo -> Bar' foo.go
package main
type Bar struct {
Baz string
}
然而,如果我尝试从 main.go 中运行以下程序:
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
combinedOutput, err := exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go").CombinedOutput()
if err != nil {
log.Fatalf("gofmt foo.go: %v. Combined output: %s", err, combinedOutput)
}
fmt.Println(string(combinedOutput))
}
我会得到一个错误:
> go run main.go
2023/01/14 23:42:07 gofmt foo.go: exit status 2. Combined output: parsing pattern 'Foo at 1:1: rune literal not terminated
exit status 1
有任何想法是什么原因导致这个错误?
英文:
In the following directory structure,
.
├── foo.go
├── go.mod
└── main.go
I have a foo.go with a simple type definition:
package main
type Foo struct {
Baz string
}
If I run gofmt -r from the command line to replace a variable name, it works:
> gofmt -r 'Foo -> Bar' foo.go
package main
type Bar struct {
Baz string
}
However, if I try to do this from main.go with the program
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
combinedOutput, err := exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go").CombinedOutput()
if err != nil {
log.Fatalf("gofmt foo.go: %v. Combined output: %s", err, combinedOutput)
}
fmt.Println(string(combinedOutput))
}
I get an error:
> go run main.go
2023/01/14 23:42:07 gofmt foo.go: exit status 2. Combined output: parsing pattern 'Foo at 1:1: rune literal not terminated
exit status 1
Any idea what is causing this?
答案1
得分: 2
你不需要在exec.Command中引用参数;引用是你的shell的一个特性,在进行系统调用时不适用。而且这也是不必要的,因为引用是用来在shell中界定参数的,但在exec.Command中,参数是作为函数调用的参数分隔的。
具体来说:
exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go")
应该改为
exec.Command("gofmt", "-r", "Foo -> Bar", "foo.go")
英文:
You don't need to quote arguments to exec.Command; quoting is a feature of your shell, and doesn't apply when you make system calls. It's also not necessary, because quoting is done to delineate arguments in the shell, but in exec.Command, the arguments are separated as arguments to the function call.
Concretely:
exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go")
should be
exec.Command("gofmt", "-r", "Foo -> Bar", "foo.go")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论