我怎么能写一个像'cd'那样的Go程序呢?
我试过运行一个命令,但它没有用.
func main() {
cmd := exec.Command("cd", "/media/")
err := cmd.Run()
log.Printf("Command finished with error: %v", err)
}
Run Code Online (Sandbox Code Playgroud)
我怎么能写一个像'cd'那样的Go程序呢?
这在POSIX系统上是不可能的(即使使用任何其他编程语言).
因为每个进程(包括父shell进程)都有自己的当前工作目录.因此cd必须是一个内置的shell(调用由shell进程本身完成的chdir(2)系统调用),它不能通过某些可执行文件完成,因为shell会分配一个新进程来运行每个命令(使用一些可执行文件,即不是内置的).
阅读一些优秀的Unix或Linux编程书,例如ALP,以获得解释.一本关于操作系统的好书,例如操作系统:三个简单的部分可以解释你为什么会这样(并且在类似POSIX或类Unix的系统中无法合理地说明).
您的代码正在分支(使用cmd.Run)一个新进程,并且该子进程仅更改其工作目录.另请参见fork(2)&execve(2)&path_resolution(7).
要在Go代码中调用 chdir(2)系统调用,请使用os.Chdir.这只会影响你的进程(以及fork(2)创建的所有未来子进程,它继承了父进程的工作目录),当然也不会改变父进程的工作目录(通常是你的shell) .
要获取当前进程的当前工作目录(使用getcwd(2)系统调用),请使用os.GetwdGo代码(并查看此代码).
在Linux上,您可以使用/proc/(请参阅proc(5)了解详细信息)来查询其他进程的工作目录.例如,ls -l /proc/$$/cwd在shell中运行.在Go代码中,你将在类似的路径上使用os.Readlink/proc/1234/cwd.当然你不能改变其他进程的工作目录(你可以改变的唯一工作目录是你自己的进程,使用chdir( 2))
正如David Budsworth评论的那样,你可以采用一种奇怪的约定:1.你的prog程序在标准输出上写一个有效的(并且适当引用shell)目录路径,而不是别的.2.你总是prog在命令替换中使用该程序,例如cd $(prog args...)(它可能成为shell函数或别名的主体等等),然后你的shell(不是你的prog)会改变目录作为程序的输出.