如何在Golang中执行一个简单的Windows命令?

huangapple go评论91阅读模式
英文:

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 (
	&quot;fmt&quot;
	&quot;time&quot;
	&quot;github.com/go-cmd/cmd&quot;
)

func main() {
	// Start a long-running process, capture stdout and stderr
	findCmd := cmd.NewCmd(&quot;find&quot;, &quot;/&quot;, &quot;--name&quot;, &quot;needle&quot;)
	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() {
		&lt;-time.After(1 * time.Hour)
		findCmd.Stop()
	}()

	// Check if command is done
	select {
	case finalStatus := &lt;-statusChan:
		// done
	default:
		// no, still running
	}

	// Block waiting for command to exit, be stopped, or be killed
	finalStatus := &lt;-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(&quot;cmd&quot;, &quot;/C&quot;, &quot;dir&quot;, &quot;d:\\&quot;)
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Run()

huangapple
  • 本文由 发表于 2012年10月22日 17:18:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/13008255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定