【问题标题】:How to change the shell's current working directory in Go?如何在 Go 中更改 shell 的当前工作目录?
【发布时间】:2020-05-21 11:24:55
【问题描述】:

我想用 Go 实现 cd 命令,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
    }
}

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

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

【问题讨论】:

标签: go


【解决方案1】:

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

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

Shell 将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)
    }
}

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

【讨论】:

    【解决方案2】:

    我没有完整的解决方案,但值得一提的是,您可以加载 golang 内置。如果我找到/制作一个,我会用更完整的实现来更新这个答案。

    Bash(和许多其他 shell)支持可加载的内置函数。 This library, and others 支持内置,但不清楚如何修改shell变量(如PWD)。

    该名称是对用于加载这些扩展的enable 内置函数的一个游戏。见https://linux.die.net/man/1/enable

    【讨论】:

      猜你喜欢
      • 2014-12-02
      • 2015-02-22
      • 2013-08-13
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多