当传递的参数是先前 运行 exec 的输出时,为什么 os/exec 命令无法按预期工作?
Why does os/exec command not work as expected when passed argument is the output of previously run exec?
我正在尝试使用 golang 在浏览器上打开给定的 URL。当我使用此代码时,它按预期工作并在浏览器中打开给定的 URL:
func main() {
url := "https://google.com"
fmt.Printf(url)
cmd := exec.Command("open", url)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
}
}
输出(打开浏览器):
~/workspace/go/so ❯ go run main.go
https://google.com%
但是当我使用 exec.Command("echo", "https://google.com")
的输出作为第二个 exec.Command
调用的参数时,程序 returns 出现如下错误:
func main() {
output, err := exec.Command("echo", "https://google.com").Output()
if err != nil {
fmt.Println(err)
}
url := string(output)
fmt.Printf(url)
cmd := exec.Command("open", url)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
}
}
输出(错误中URL后面有当前目录路径):
~/workspace/go/so ❯ go run main.go
https://google.com
exit status 1: The file /Users/kadir/workspace/go/so/https:/google.com
does not exist.
我在第二个代码块中做错了什么?
我的 go 版本是 1.17 和 go.mod
文件是这样的:
module so
go 1.17
require github.com/urfave/cli/v2 v2.3.0
require (
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
)
正如@JimB 所指出的,在命令输出的末尾有一个隐含的换行符。
最好使用 fmt
%q
动词来确保输出没有恶意字符:
fmt.Printf("%q\n", url) // "https://google.com\n"
因此,请在源头解决此问题,使用 echo -n
取消换行符:
output, err := exec.Command("echo", "-n", "https://google.com").Output()
或在接收端:
url = strings.TrimSpace(url)
我正在尝试使用 golang 在浏览器上打开给定的 URL。当我使用此代码时,它按预期工作并在浏览器中打开给定的 URL:
func main() {
url := "https://google.com"
fmt.Printf(url)
cmd := exec.Command("open", url)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
}
}
输出(打开浏览器):
~/workspace/go/so ❯ go run main.go
https://google.com%
但是当我使用 exec.Command("echo", "https://google.com")
的输出作为第二个 exec.Command
调用的参数时,程序 returns 出现如下错误:
func main() {
output, err := exec.Command("echo", "https://google.com").Output()
if err != nil {
fmt.Println(err)
}
url := string(output)
fmt.Printf(url)
cmd := exec.Command("open", url)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
}
}
输出(错误中URL后面有当前目录路径):
~/workspace/go/so ❯ go run main.go
https://google.com
exit status 1: The file /Users/kadir/workspace/go/so/https:/google.com
does not exist.
我在第二个代码块中做错了什么?
我的 go 版本是 1.17 和 go.mod
文件是这样的:
module so
go 1.17
require github.com/urfave/cli/v2 v2.3.0
require (
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
)
正如@JimB 所指出的,在命令输出的末尾有一个隐含的换行符。
最好使用 fmt
%q
动词来确保输出没有恶意字符:
fmt.Printf("%q\n", url) // "https://google.com\n"
因此,请在源头解决此问题,使用 echo -n
取消换行符:
output, err := exec.Command("echo", "-n", "https://google.com").Output()
或在接收端:
url = strings.TrimSpace(url)