当我创建自己的shell时,我无法执行我能在Linux shell中执行的cd命令。那是为什么?
答案 0 :(得分:5)
这可能是因为cd
命令必须内置到shell中,而不是外部和执行的内容。如果外部命令更改了目录,则它对父shell没有影响。并且没有命令/bin/cd
或/usr/bin/cd
。
我不明白“如果外部命令改变了目录,它对父shell没有影响”。
通常,当shell执行命令时,它执行fork()
并且子进程使用exec()
来执行用户输入的命令。例如,如果输入的命令为“ls /
”,则shell会安排使用两个参数/bin/ls
和ls
执行/
。但是,如果所选命令执行chdir()
系统调用,则会影响子进程,但不会影响父shell。因此,shell必须处理cd
命令本身,而不是fork()
和exec()
。
请注意,在DOS中,.BAT文件可以cd
,它会影响cmd.exe
进程。这在Unix中不会发生 - 子进程不能影响父进程的当前目录。
答案 1 :(得分:2)
Jonathan Leffler解释了为什么会这样,但我想提供一种解决方法,以防您真正需要此功能。在bash中(您没有指定,所以我假设),source
命令可用于在CURRENT shell进程中执行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
调用它。
答案 2 :(得分:0)
这很简单:
cd
不是命令。试试这个:
- whereis ls
- whereis cd
(见差异)
cd
是shell的属性,因此如果您要创建shell,则必须支持cd
。这样看,当执行ls时,它需要知道pwd。所以,它是你的自定义shell来处理目录。所以,它的shell必须支持cd。
我想我已经说清楚了。