Golang中exec.Command()无法识别Cd的问题如何解决

Golang中exec.Command()无法识别Cd的问题如何解决 你好。我发现了一些奇怪的事情(嗯,对我来说,希望背后没有魔法)。

这个运行得很好:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	out, err := exec.Command("ls", "-la").Output()
	if err != nil {
		fmt.Printf("%s", err)
	} else {
		fmt.Println(string(out[:]))
	}
}

但下面的代码不行:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	out, err = exec.Command("cd", "../mydir").Output()
	if err != nil {
		fmt.Printf("%s", err)
	} else {
		fmt.Println(string(out[:]))
	}

}

我收到了以下错误:

exec: "cd": executable file not found in $PATH

为什么 exec.Command() 无法识别 cd

信息

  • Windows 10 下的 WSL 1 (Ubuntu 20.4)
  • go version go1.16.3 linux/amd64

更多关于Golang中exec.Command()无法识别Cd的问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

哦,天哪。谢谢,非常感谢。我猜(并且希望)是类似这样的原因,但我很惊讶,因为我在其他几种语言的相应系统命令中都使用了 cd,而且它总是有效的。

谢谢!

更多关于Golang中exec.Command()无法识别Cd的问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


cd 不是一个程序。它是你 shell 中的一个语句。你可以做类似 exec.Command("bash", "-c", "cd ../mydir") 这样的事情,但这将是徒劳的,因为 cd 改变的是当前进程(在这个例子中是 bash)的工作目录,所以你自己的程序仍然会处于其自身当前的工作目录中。

如果你想改变你的程序正在工作的目录,请使用 os.Chdir

func main() {
    err := os.Chdir("../mydir")
    if err != nil {
        log.Fatal(err)
    }
}

cd 是 shell 内置命令,不是独立的可执行文件。exec.Command() 直接执行系统命令,不通过 shell 解析,因此无法识别 shell 内置命令。

解决方案有两种:

方案1:使用 shell 执行 通过 /bin/sh/bin/bash 执行包含 cd 的命令:

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("/bin/sh", "-c", "cd ../mydir && ls -la")
    out, err := cmd.Output()
    if err != nil {
        fmt.Printf("%s", err)
    } else {
        fmt.Println(string(out))
    }
}

方案2:设置工作目录 使用 exec.Command()Dir 字段直接设置工作目录:

package main

import (
    "fmt"
    "os/exec"
    "path/filepath"
)

func main() {
    // 获取当前目录并计算目标目录
    currentDir, _ := filepath.Abs(".")
    targetDir := filepath.Join(currentDir, "../mydir")
    
    cmd := exec.Command("ls", "-la")
    cmd.Dir = targetDir  // 设置命令的工作目录
    
    out, err := cmd.Output()
    if err != nil {
        fmt.Printf("%s", err)
    } else {
        fmt.Println(string(out))
    }
}

方案3:使用 os.Chdir() 改变当前进程的工作目录

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    // 改变当前进程的工作目录
    err := os.Chdir("../mydir")
    if err != nil {
        fmt.Printf("chdir error: %s", err)
        return
    }
    
    // 现在所有后续命令都在新目录中执行
    out, err := exec.Command("ls", "-la").Output()
    if err != nil {
        fmt.Printf("%s", err)
    } else {
        fmt.Println(string(out))
    }
}

推荐使用方案2,因为它只影响单个命令的工作目录,不会改变整个进程的状态。

回到顶部