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?
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.