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.
–
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()
–
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.