为什么cd命令在我的shell程序中不起作用?

问题描述 投票:6回答:3

当我创建自己的shell时,我无法执行cd命令,而该命令在Linux shell中是可以执行的。为什么会这样?

linux
3个回答
6
投票

这可能是因为cd命令必须内置到外壳中,而不是外部的并执行。如果外部命令更改了目录,则它对父外壳无效。 (即使在Linux和macOS系统上通常使用命令/bin/cd/usr/bin/cd,执行该命令也会更改该进程的目录,但对调用它的进程没有影响。)


我不理解“如果外部命令更改了目录,则对父外壳无效”。

[通常,shell执行命令时,它将执行fork(),并且子进程使用exec()执行用户输入的命令。例如,如果输入的命令为'ls /',则Shell安排使用两个参数/bin/lsls执行/。但是,如果选择的命令执行chdir()系统调用,则将影响子进程,但不影响父Shell。因此,外壳程序必须自己处理cd命令,而不是通过fork()exec()

[请注意,在DOS中,.BAT文件可以执行cd,它会影响cmd.exe进程。在Unix中不会发生这种情况-子进程不会影响父进程的当前目录。


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对其进行调用。


0
投票

这很简单:

  • cd不是命令。

尝试一下:

-whereis ls

-whereis cd

(查看区别)

  • cd是外壳的属性,因此,如果要制作外壳,则必须支持cd

这样看,当执行ls时,它需要知道pwd。因此,它将是您处理目录的自定义外壳程序。因此,它是必须支持cd的外壳。

我想我已经说清楚了。

© www.soinside.com 2019 - 2024. All rights reserved.