在 Go 中执行带有参数的命令?
exec command with parameters in Go?
在我的 shell 中,我可以执行命令 acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
并获得输出。
现在我想在 go 中执行此操作,我的代码如下:
cmd := exec.Command("bash", "-c", "acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please");
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("issue failed with error: %s\n", err)
}
fmt.Printf("combined out:\n%s\n", string(out))
但我收到错误 exit status 1
。
正如评论所说,我将论点分开:
exec.Command("bash", "-c", "acme.sh", "--issue", "--dns", "-d exmaple.com", "--yes-I-know-dns-manual-mode-enough-go-ahead-please");
但结果是不带参数执行acme.sh
将此脚本用作 acme.sh
#!/bin/bash
echo "$*"
与给定的程序在同一目录下出现您报告的错误
但是,如果我将当前目录添加到 shell PATH
export PATH=.:$PATH
然后程序按预期执行,在我的版本中
$ go run c.go
combined out:
--issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
好的,这就是 bash -c 将单个字符串作为命令的情况(稍后会详细介绍)
如果命令是这样发出的
cmd := exec.Command("acme.sh", "--issue", "--dns", "-d exmaple.com", "--
yes-I-know-dns-manual-mode-enough-go-ahead-please")
然后在稍后对您的问题状态进行编辑时,命令 acme.sh 是 运行 没有参数。
问题在于 bash -c
的行为方式。
来自手册页
bash interprets the following options when it
is invoked:
-c If the -c option is present, then commands are read from the
first non-option argument command_string. If there are argu‐
ments after the command_string, they are assigned to the
positional parameters, starting with [=14=].
在您的情况下,这意味着 bash -c
的第一个参数被接受为命令。其他参数丢失,因为它们是新 bash shell 的位置参数,而不是 acme.sh
命令
有关 bash -c
https://unix.stackexchange.com/questions/144514/add-arguments-to-bash-c
的更多详细信息,请参阅此内容
最后,在这种情况下我会做什么:跳过 "bash" "-c"
,确保脚本有正确的 bang 行并依赖内核 binfmt 处理程序
从 err 中排除 exit status 1
将得到正确的结果。
cmd := exec.Command("bash", "-c", "acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please");
out, err := cmd.CombinedOutput()
if err != nil && err.Error() != "exit status 1" {
log.Fatalf("issue failed with error: %s\n", err)
}
fmt.Printf("combined out:\n%s\n", string(out))
在我的 shell 中,我可以执行命令 acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
并获得输出。
现在我想在 go 中执行此操作,我的代码如下:
cmd := exec.Command("bash", "-c", "acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please");
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("issue failed with error: %s\n", err)
}
fmt.Printf("combined out:\n%s\n", string(out))
但我收到错误 exit status 1
。
正如评论所说,我将论点分开:
exec.Command("bash", "-c", "acme.sh", "--issue", "--dns", "-d exmaple.com", "--yes-I-know-dns-manual-mode-enough-go-ahead-please");
但结果是不带参数执行acme.sh
将此脚本用作 acme.sh
#!/bin/bash
echo "$*"
与给定的程序在同一目录下出现您报告的错误
但是,如果我将当前目录添加到 shell PATH
export PATH=.:$PATH
然后程序按预期执行,在我的版本中
$ go run c.go
combined out:
--issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
好的,这就是 bash -c 将单个字符串作为命令的情况(稍后会详细介绍)
如果命令是这样发出的
cmd := exec.Command("acme.sh", "--issue", "--dns", "-d exmaple.com", "--
yes-I-know-dns-manual-mode-enough-go-ahead-please")
然后在稍后对您的问题状态进行编辑时,命令 acme.sh 是 运行 没有参数。
问题在于 bash -c
的行为方式。
来自手册页
bash interprets the following options when it is invoked:
-c If the -c option is present, then commands are read from the first non-option argument command_string. If there are argu‐ ments after the command_string, they are assigned to the positional parameters, starting with [=14=].
在您的情况下,这意味着 bash -c
的第一个参数被接受为命令。其他参数丢失,因为它们是新 bash shell 的位置参数,而不是 acme.sh
命令
有关 bash -c
https://unix.stackexchange.com/questions/144514/add-arguments-to-bash-c
最后,在这种情况下我会做什么:跳过 "bash" "-c"
,确保脚本有正确的 bang 行并依赖内核 binfmt 处理程序
从 err 中排除 exit status 1
将得到正确的结果。
cmd := exec.Command("bash", "-c", "acme.sh --issue --dns -d exmaple.com --yes-I-know-dns-manual-mode-enough-go-ahead-please");
out, err := cmd.CombinedOutput()
if err != nil && err.Error() != "exit status 1" {
log.Fatalf("issue failed with error: %s\n", err)
}
fmt.Printf("combined out:\n%s\n", string(out))