2010-09-18 72 views
5

当我创建我自己的shell时,我无法执行我能够在Linux shell中执行的cd命令。这是为什么?为什么cd命令不能在我的shell程序中工作?

+0

如果错误是“未找到命令”,则可能与“PATH”有关。 'echo $ PATH'说什么? – 2010-09-18 05:38:25

+1

你创建了你自己的shell?没有'cd'命令?你为什么这么做? – Johnsyweb 2010-09-18 05:41:53

回答

5

这可能是因为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中不会发生 - 子进程不会影响父进程的当前目录。

+0

感谢您的答案,但我不明白的行“如果外部命令更改目录,它对父shell没有影响”。 – phani987 2010-09-18 05:36:21

+2

Unix/Linux和DOS是相同的,每个进程都有自己的当前目录。不同的是,在DOS中,BAT文件(和嵌套的BAT文件)由当前的cmd.exe进程运行,而在Unix/Linux中,运行shell脚本启动一个新的shell进程。在Unix/Linux中,如果在脚本中运行CD,它将更改该shell的当前目录,这将影响同一脚本中后续的命令。但启动脚本的shell不受影响。 – 2010-09-18 06:01:02

+0

@阿德里安:你是对的 - 我想知道是否要留下最后一段,或者是否会混淆OP。你的解释比我的更清楚。 – 2010-09-18 06:13:02

2

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

+0

现在我重读了这个问题,这可能很难打出:-)哦。 – 2010-09-18 07:19:22

+0

+1:当shell在内部实现了'cd'命令(以及''source'或'.'命令)时,这很有用。 AFAICT,问题是关于一个没有实现'cd'的home-brew shell(通过'chdir()'系统调用),因此没有任何资源可以帮助改变目录直到它实现。 – 2010-09-18 07:21:53

+0

是的,我收集了我的心理解析器的第二遍。 – 2010-09-18 07:24:56

0

这很简单,只要:

  • cd不是命令。

试试这个:

- whereis ls

- whereis cd

(见的区别)

  • cd是外壳的特性,因此,如果您正在一个外壳,那么你必须支持cd

看到这样,当执行ls时就需要知道pwd。所以,它是你的自定义shell来处理目录。所以,它的外壳必须支持cd。

我想我已经说清楚了。

相关问题