Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have seen the existing solutions to run a windows command from a Golang program but none works for me. My aim is to open a .png file from the go program.

Below is sample program. It does not open the image file. I am just trying with dir for testing.

package main
import (
    "log"
    "os/exec"
    "runtime"
func main() {
    cmd := exec.Command("ls", "-lah")
    if runtime.GOOS == "windows" {
        cmd = exec.Command("cmd", "dir")
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    if err != nil {
        log.Fatalf("cmd.Run() failed with %s\n", err)

I have also tried cmd = exec.Command("dir") in line 13. The program just exists without any error or output. Seems like a successful execution as there is no error being shown to me. I tried a few variations but no success.

I am using VSCode and tried running this program through built-in cmd and wsl in VSCode. When I use wsl to run the program, it shows the output of ls -lah but nothing for cmd. I don't know if there is some way to direct windows output. Any help is appreciated. Thanks.

It will not but I also tried cmd = exec.Command("dir") as well. Brits explanation clears it. Thanks – Ab1010 Feb 24, 2020 at 3:30

cmd.exe is the windows command interpreter; if you wish to pass it a command to run you need to use the /c parameter - e.g. cmd /c dir. If you enter cmd dir at a command prompt you will get the same result as your current go application (except that the cmd prompt will not automatically close due to the lack of stdin). If you run cmd /? this is explained as:

/C Carries out the command specified by string and then terminates

So to fix your application use the following:

cmd = exec.Command("cmd", "/c", "dir")

An alternative way of doing this is to pass the command in via stdin:

cmd := exec.Command("cmd")
cmd.Stdout = os.Stdout
stdin, err := cmd.StdinPipe()
if err != nil {
    log.Fatal(err)
go func() {
    defer stdin.Close()
    io.WriteString(stdin, "dir\n")
err = cmd.Run()
if err != nil {
    log.Fatalf("cmd.Run() failed with %s\n", err)

A simple way to open your BMP file is cmd = exec.Command("explorer.exe", "test.bmp") (this will open it with whatever the default application is).

Note: The reason you need to run cmd in the first place is that dir is an internal command provided by cmd.exe (if you run dir dir.* /s in the windows folder you won't find anything because there is no dir.exe or similar; its embedded in cmd.exe).

Note2: If you are were running ls/dir in this way to get the contents of a folder (rather than as an example) then ioutil.ReadDir is a better option.

As explained by Brits, the error seems to manifest only when a Windows internal command is request. So, to circumvent the check done on the file path, I created a local batch file with the same name as the Windows internal command, e.g. if I wanted to run an "ECHO" command, I can create a echo.bat file that contains "@ECHO %1". Just tested and the same code is now working on both Windows and Linux, e.g.:

    cmd := exec.Command(os.Args[1], os.Args[2:]...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Run()
                Welcome to SO! Please refer the answer youre talking about. When you say "above" it can be misleading as other answers can be added and get more upvotes than yours. Or your answer can become the answer and go to the top.
– GabrielOshiro
                Jul 14, 2020 at 20:51
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.