我想用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中更改我的工作目录?
答案 0 :(得分:2)
您无法执行此操作;每个子进程都有从父进程继承的自己的工作目录。在这种情况下,您的cd
从其父级(您的shell)中获取其工作目录。子进程无法更改父进程的目录或任何其他状态。
这是基本的过程分离。允许子进程影响其父进程将遇到各种安全性和可用性问题。
Shell将cd
实现为“特殊内置”。它不是外部二进制文件:
$ where cd
cd: shell built-in command
换句话说,当外壳程序运行cd
命令时,它与外壳程序其余部分的运行过程相同。
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)
}
}
无论使用哪种语言来实现,都无法在外部二进制文件中实现。
答案 1 :(得分:1)
我没有完整的解决方案,但是值得一提的是,您可以加载golang内置函数。如果找到/制作一个,我将使用更完整的实现来更新此答案。
Bash(和许多其他Shell)支持可加载的内置函数。 This library,and others支持内置函数,但尚不清楚如何修改shell变量(例如PWD
)。
该名称是内置enable
上的名称,用于加载这些扩展名。参见https://linux.die.net/man/1/enable