为什么cd命令不能在我的shell程序中工作?
这可能是因为cd
命令必须内置到shell中,而不是外部和执行的东西。如果外部命令更改了目录,则它对父shell没有影响。没有命令/bin/cd
或/usr/bin/cd
。
我不懂行“如果外部命令更改目录,这对父shell没有任何影响”。
通常情况下,当一个shell执行命令,它fork()
和子进程使用exec()
执行由用户输入的命令。例如,如果输入的命令是'ls /
',那么shell会安排执行/bin/ls
,并带有两个参数ls
和/
。但是,如果选择的命令执行chdir()
系统调用,则会影响子进程,但不会影响父shell。所以,外壳必须处理cd
命令本身,而不是通过fork()
和exec()
。
请注意,在DOS中,.BAT文件可以执行cd
并且它会影响cmd.exe
进程。这在Unix中不会发生 - 子进程不会影响父进程的当前目录。
感谢您的答案,但我不明白的行“如果外部命令更改目录,它对父shell没有影响”。 – phani987 2010-09-18 05:36:21
Unix/Linux和DOS是相同的,每个进程都有自己的当前目录。不同的是,在DOS中,BAT文件(和嵌套的BAT文件)由当前的cmd.exe进程运行,而在Unix/Linux中,运行shell脚本启动一个新的shell进程。在Unix/Linux中,如果在脚本中运行CD,它将更改该shell的当前目录,这将影响同一脚本中后续的命令。但启动脚本的shell不受影响。 – 2010-09-18 06:01:02
@阿德里安:你是对的 - 我想知道是否要留下最后一段,或者是否会混淆OP。你的解释比我的更清楚。 – 2010-09-18 06:13:02
Jonathan Leffler解释了为什么会出现这种情况,但我想提供一种解决方法,以防您实际需要此功能。在bash中(你没有指定,所以我假设),可以使用source
命令在CURRENT shell进程中执行shell脚本。我使用类似于下面的(虽然比较全面的)东西,带外壳的别名一起,更改为项目目录,并自动设置环境:
~:$ cat $HOME/bin/goproj
#!/bin/bash
...
export SOMEVAR=someval
cd /home/foo/src/projects/"$1"
...
~:$ alias gp
alias gp="source $HOME/bin/goproj"
~:$ gp foo
~/src/projects/foo:$ echo $SOMEVAR
someval
~/src/projects/foo:$
使用这种类型的设置,您可以修改当前shell与您正在采购的脚本中存在的任何内容。请注意,如果您直接运行'goproj',则它不适用于您已经遇到的相同问题;您必须拨打电话source
。
现在我重读了这个问题,这可能很难打出:-)哦。 – 2010-09-18 07:19:22
+1:当shell在内部实现了'cd'命令(以及''source'或'.'命令)时,这很有用。 AFAICT,问题是关于一个没有实现'cd'的home-brew shell(通过'chdir()'系统调用),因此没有任何资源可以帮助改变目录直到它实现。 – 2010-09-18 07:21:53
是的,我收集了我的心理解析器的第二遍。 – 2010-09-18 07:24:56
这很简单,只要:
-
cd
不是命令。
试试这个:
- whereis ls
- whereis cd
(见的区别)
-
cd
是外壳的特性,因此,如果您正在一个外壳,那么你必须支持cd
。
看到这样,当执行ls时就需要知道pwd。所以,它是你的自定义shell来处理目录。所以,它的外壳必须支持cd。
我想我已经说清楚了。
如果错误是“未找到命令”,则可能与“PATH”有关。 'echo $ PATH'说什么? – 2010-09-18 05:38:25
你创建了你自己的shell?没有'cd'命令?你为什么这么做? – Johnsyweb 2010-09-18 05:41:53