首页 > 解决方案 > 如何在 Go 中更改 shell 的当前工作目录?

问题描述

我想cd用 Go 实现命令,main.go

func main() {
    flag.Parse()
    if flag.NArg() == 0 {
        curUser, err := user.Current()
        if err != nil {
            log.Fatal(err)
        }
        os.Chdir(curUser.HomeDir)
        // or like this
        // cmd := exec.Command("cd", curUser.HomeDir)
        fmt.Println(os.Getwd())   // ok in application
    }
}

但是当我go run main.go在 shell 中运行时,它仍然没有切换到我的主目录。

那么如何通过运行 go 文件来更改 shell 中的工作目录?

代码运行

标签: go

解决方案


你不能这样做;每个子进程都有自己的从父进程继承的工作目录。在这种情况下,您cd从其父级(您的外壳)获取其工作目录。子进程不能更改父进程的目录或任何其他状态。

这是基本的流程分离。允许子进程影响其父进程会带来各种安全性和可用性问题。

外壳实现cd为“特殊内置”。它不是外部二进制文件:

$ where cd
cd: shell built-in command

换句话说,当 shell 运行cd命令时,它与 shell 的其余部分在同一进程中运行。

shell 的 REPL 的基本逻辑类似于:

for {
    line := waitForInputLine()
    switch {
        case strings.HasPrefix(line, "cd"):
            os.chdir(strings.Split(line, " ")[1])

        // ..check other builtins and special cases./

        default:
            runBinary(line)
    }
}

无论您使用哪种语言来实现它,都无法在外部二进制文件中实现它。


推荐阅读