英文:
How to execute a simple Windows command in Golang?
问题
如何运行一个简单的Windows命令?
这个命令:
exec.Command("del", "c:\\aaa.txt")
.. 输出以下信息:
> del: 在%path%中找不到可执行文件
我做错了什么?
英文:
How to run a simple Windows command?
This command:
exec.Command("del", "c:\\aaa.txt")
.. outputs this message:
> del: executable file not found in %path%
What am I doing wrong?
答案1
得分: 56
我遇到了和你一样的错误。
但是dystroy是正确的:你不能运行del
或者其他内置在cmd
中的命令,因为没有del.exe
文件(或者其他任何del可执行文件)。
我用以下代码使其工作:
package main
import(
"fmt"
"os/exec"
)
func main() {
var c *exec.Cmd
switch runtime.GOOS{
case "windows":
c = exec.Command("cmd", "/C", "del", "D:\\a.txt")
default://Mac & Linux
c = exec.Command("rm", "-f", "/d/a.txt")
}
if err := c.Run(); err != nil {
fmt.Println("Error: ", err)
}
}
英文:
I got the same error as you.
But dystroy is correct: You can't run del
or any other command built into cmd
because there is no del.exe
file (or any other del-executable for that matter).
I got it to work with:
package main
import(
"fmt"
"os/exec"
)
func main() {
var c *exec.Cmd
switch runtime.GOOS{
case "windows":
c = exec.Command("cmd", "/C", "del", "D:\\a.txt")
default://Mac & Linux
c = exec.Command("rm", "-f", "/d/a.txt")
}
if err := c.Run(); err != nil {
fmt.Println("Error: ", err)
}
}
答案2
得分: 8
你需要一个Windows cmd来执行你的dir
命令。
尝试这样做:
cmd := exec.Command("cmd", "/C", "dir").Output()
(抱歉,现在没有Windows电脑来检查它)
英文:
You need a Windows cmd to execute your dir
command.
Try this :
cmd := exec.Command("cmd", "/C", "dir").Output()
(sorry, no Windows computer to check it right now)
答案3
得分: 3
找到另一种解决方案。创建一个包含以下内容的批处理文件:del c:\aaa.txt
然后像这样调用它:
exec.Command("c:\\del.bat").Run()
英文:
Found another solution too. Create a batch file that contains the following: del c:\aaa.txt
Then call it like this:
exec.Command("c:\\del.bat").Run()
答案4
得分: 2
如果你需要cmd的输出:
如果 c, err := exec.Command("cmd","/c","del","a.txt").CombinedOutput(); err != nil {
log.Fatal(err)
} else {
fmt.Printf("%s\n", c)
}
英文:
In case you need the output of cmd:
if c, err := exec.Command("cmd","/c","del","a.txt").CombinedOutput(); err != nil {
log.Fatal(err)
} else {
fmt.Printf("%s\n", c)
}
答案5
得分: 1
根据文档,在Windows中,进程以单行字符串的形式接收命令,并进行一些解析。Exec的Command函数通过使用CommandLineToArgvW将所有参数组合在一起来构建命令字符串,尽管这是最常见的引用算法,但并不适用于每个应用程序。像msiexec.exe和cmd.exe这样的应用程序使用不兼容的取消引用算法,因此需要额外的努力。
这里是使用PowerShell的不同示例
package main
import (
"os/exec"
"fmt"
"log"
)
func main() {
out, err := exec.Command("powershell","remove-item","aaa.txt").Output()
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("%s",out)
}
英文:
Ok let's see, according to the documentation, in windows, processes receive commands as a single line string and do some parsing of their own. Exec's Command function builds the command string by combining all arguments together using CommandLineToArgvW, that despite being the most common quoting algorithm doesn't work for every application. Applications like msiexec.exe and cmd.exe use an incompatible unquoting algorithm, hence the extra mile.
Heres a different example using powershell
package main
import (
"os/exec"
"fmt"
"log"
)
func main() {
out, err := exec.Command("powershell","remove-item","aaa.txt").Output()
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("%s",out)
}
答案6
得分: 1
你可以尝试使用github.com/go-cmd/cmd模块。因为Golang默认情况下无法使用syscall。
示例:
import (
"fmt"
"time"
"github.com/go-cmd/cmd"
)
func main() {
// 启动一个长时间运行的进程,捕获stdout和stderr
findCmd := cmd.NewCmd("find", "/", "--name", "needle")
statusChan := findCmd.Start() // 非阻塞
ticker := time.NewTicker(2 * time.Second)
// 每2秒打印stdout的最后一行
go func() {
for range ticker.C {
status := findCmd.Status()
n := len(status.Stdout)
fmt.Println(status.Stdout[n-1])
}
}()
// 1小时后停止命令
go func() {
<-time.After(1 * time.Hour)
findCmd.Stop()
}()
// 检查命令是否完成
select {
case finalStatus := <-statusChan:
// 完成
default:
// 未完成,仍在运行
}
// 阻塞等待命令退出、停止或被杀死
finalStatus := <-statusChan
}
英文:
you can try use github.com/go-cmd/cmd module.
because golang can not use syscall by default.
example:
import (
"fmt"
"time"
"github.com/go-cmd/cmd"
)
func main() {
// Start a long-running process, capture stdout and stderr
findCmd := cmd.NewCmd("find", "/", "--name", "needle")
statusChan := findCmd.Start() // non-blocking
ticker := time.NewTicker(2 * time.Second)
// Print last line of stdout every 2s
go func() {
for range ticker.C {
status := findCmd.Status()
n := len(status.Stdout)
fmt.Println(status.Stdout[n-1])
}
}()
// Stop command after 1 hour
go func() {
<-time.After(1 * time.Hour)
findCmd.Stop()
}()
// Check if command is done
select {
case finalStatus := <-statusChan:
// done
default:
// no, still running
}
// Block waiting for command to exit, be stopped, or be killed
finalStatus := <-statusChan
}
答案7
得分: 1
c := exec.Command("cmd", "/C", "dir", "d:\")
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Run()
英文:
c := exec.Command("cmd", "/C", "dir", "d:\\")
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Run()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论