如何在Go中更改Shell的当前工作目录?

I want implement the cd command with 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
    }
}

But when I run go run main.go in shell, it still not switch to my home directory.

So how can I change my working directory in shell by running go files?

code running

You can't do this; every child process has its own working directory inherited from the parent. In this case, your cd gets its working directory from its parent (your shell). A child process can't change the directory – or any other state – of the parent process.

This is basic process separation. Allowing child processes to influence their parent would have all sorts of security and usability issues.

Shells implement cd as a "special builtin". It's not an external binary:

$ where cd
cd: shell built-in command

In other words, when the shell runs the cd command it's run in the same process as the rest of the shell.

The basic logic of a shell's REPL looks something like:

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

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

        default:
            runBinary(line)
    }
}

There is no way you can implement that in an external binary, no matter which language you use to implement it.