我如何编写一个与cd一样的Go程序?
我尝试运行命令,但是没有用。
func main() {
cmd := exec.Command("cd", "/media/")
err := cmd.Run()
log.Printf("Command finished with error: %v", err)
}
答案 0 :(得分:5)
我如何编写一个与cd一样的Go程序?
这在POSIX系统上不可能 (即使使用其他编程语言也是如此)。
因为每个process(包括父shell进程)都具有自己的 own 当前working directory。因此cd
必须是shell builtin(调用chdir(2)系统调用由shell进程本身完成),它不能由某些executable完成,因为shell会分叉a运行每个命令的新过程(使用一些可执行文件,即不是内置文件)。
阅读一些不错的Unix或Linux编程书籍,例如ALP,以获得解释。一本关于Operating systems的好书,例如Operating systems: three easy pieces会向您解释为什么会这样(并且在类似POSIX或类Unix的系统中不可能这样)。
您的代码是forking(带有cmd.Run
)的新进程,并且 子进程仅正在更改其工作目录。另请参见fork(2)和execve(2)和path_resolution(7)。
要在Go代码中调用chdir(2)系统调用,请使用os.Chdir
。那只会影响您的流程(以及fork(2)创建的所有将来的子流程,它们都继承其父流程的工作目录),当然不会更改您的父流程的工作目录(通常是您的shell) )。
要获取当前进程的当前工作目录(通过getcwd(2)系统调用),请在Go代码中使用os.Getwd
(并查看this)。
在Linux上,您可以使用/proc/
(有关详细信息,请参见proc(5))来查询其他进程的工作目录。例如,在您的Shell中运行ls -l /proc/$$/cwd
。在Go代码中,您将在/proc/1234/cwd
等路径上使用os.Readlink。当然,您不能更改其他进程的工作目录(唯一可以更改的工作目录是您自己的过程,使用chdir(2))
根据David Budsworth的评论,您可以采用一种奇怪的惯例:1.您的prog
程序在以下位置写入有效的目录路径(并在外壳程序中适当引用):标准输出,仅此而已。 2.您总是将prog
程序与command substitution一起使用,例如cd $(prog args...)
(可能成为shell function或{ {3}}等),那么您的外壳程序(而不是prog
)将更改程序输出的目录。