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

时间:2022-08-01 07:03:11

When I created my own shell, I am not able to execute cd command which I am able to do in the Linux shell. Why is that?

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

3 个解决方案

#1


5  

That's probably because the cd command has to be built into the shell, not something external and executed. If an external command changed directory, it has no effect on the parent shell. And there is no command /bin/cd or /usr/bin/cd.

这可能是因为cd命令必须内置到shell中,而不是外部和执行的东西。如果外部命令更改了目录,则它对父shell没有影响。并且没有命令/ bin / cd或/ usr / bin / cd。


I do not understand the line "If the external command changed directory, it has no effect on the parent shell".

我不明白“如果外部命令改变了目录,它对父shell没有影响”。

Normally, when a shell executes a command, it does fork() and the child process uses exec() to execute the command entered by the user. For example, if the entered command is 'ls /', the shell arranges to execute /bin/ls with two arguments, ls and /. However, if the command selected executes the chdir() system call, that affects the child process, but does not affect the parent shell. So, the shell has to handle the cd command itself, not via fork() and exec().

通常,当shell执行命令时,它执行fork(),子进程使用exec()来执行用户输入的命令。例如,如果输入的命令是'ls /',则shell安排执行带有两个参数ls和/的/ bin / ls。但是,如果所选命令执行chdir()系统调用,则会影响子进程,但不会影响父shell。因此,shell必须处理cd命令本身,而不是通过fork()和exec()。

Note that in DOS, a .BAT file can do cd and it affects the cmd.exe process. This does not happen in Unix - a child process cannot affect the current directory of the parent process.

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

#2


2  

Jonathan Leffler explained why this was, but I wanted to offer a workaround in case you actually need this functionality. In bash (you didn't specify, so I'll assume), the source command can be used to execute a shell script in the CURRENT shell process. I use something similar to the below (though more comprehensive), along with a shell alias, to change to project directories and automagically set up the environment:

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:$

Using this type of setup, you can modify the current shell with whatever exists in the script you're sourcing. Note that if you ran 'goproj' directly, it wouldn't work for the same problem you're already experiencing; you must call it with source.

使用此类设置,您可以使用您要采购的脚本中存在的任何内容修改当前shell。请注意,如果您直接运行'goproj',它将无法解决您遇到的同一问题;你必须用source来调用它。

#3


0  

This is as simple as :

这很简单:

  • cd is not a command.
  • cd不是命令。

Try this :

试试这个 :

-- whereis ls

- whereis ls

-- whereis cd

- 哪里是cd

(See the difference)

(看到不同)

  • cd is property of the shell, so if you are making a shell then you have to support cd.
  • cd是shell的属性,所以如果你要创建一个shell,那么你必须支持cd。

See it this way, when ls is executed then it needs to know the pwd. So, it your custom shell that would handle the directory. So, its the shell that has to support cd.

这样看,当执行ls然后它需要知道pwd。因此,它是您处理目录的自定义shell。所以,它的shell必须支持cd。

I think I made myself clear.

我想我已经说清楚了。

#1


5  

That's probably because the cd command has to be built into the shell, not something external and executed. If an external command changed directory, it has no effect on the parent shell. And there is no command /bin/cd or /usr/bin/cd.

这可能是因为cd命令必须内置到shell中,而不是外部和执行的东西。如果外部命令更改了目录,则它对父shell没有影响。并且没有命令/ bin / cd或/ usr / bin / cd。


I do not understand the line "If the external command changed directory, it has no effect on the parent shell".

我不明白“如果外部命令改变了目录,它对父shell没有影响”。

Normally, when a shell executes a command, it does fork() and the child process uses exec() to execute the command entered by the user. For example, if the entered command is 'ls /', the shell arranges to execute /bin/ls with two arguments, ls and /. However, if the command selected executes the chdir() system call, that affects the child process, but does not affect the parent shell. So, the shell has to handle the cd command itself, not via fork() and exec().

通常,当shell执行命令时,它执行fork(),子进程使用exec()来执行用户输入的命令。例如,如果输入的命令是'ls /',则shell安排执行带有两个参数ls和/的/ bin / ls。但是,如果所选命令执行chdir()系统调用,则会影响子进程,但不会影响父shell。因此,shell必须处理cd命令本身,而不是通过fork()和exec()。

Note that in DOS, a .BAT file can do cd and it affects the cmd.exe process. This does not happen in Unix - a child process cannot affect the current directory of the parent process.

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

#2


2  

Jonathan Leffler explained why this was, but I wanted to offer a workaround in case you actually need this functionality. In bash (you didn't specify, so I'll assume), the source command can be used to execute a shell script in the CURRENT shell process. I use something similar to the below (though more comprehensive), along with a shell alias, to change to project directories and automagically set up the environment:

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:$

Using this type of setup, you can modify the current shell with whatever exists in the script you're sourcing. Note that if you ran 'goproj' directly, it wouldn't work for the same problem you're already experiencing; you must call it with source.

使用此类设置,您可以使用您要采购的脚本中存在的任何内容修改当前shell。请注意,如果您直接运行'goproj',它将无法解决您遇到的同一问题;你必须用source来调用它。

#3


0  

This is as simple as :

这很简单:

  • cd is not a command.
  • cd不是命令。

Try this :

试试这个 :

-- whereis ls

- whereis ls

-- whereis cd

- 哪里是cd

(See the difference)

(看到不同)

  • cd is property of the shell, so if you are making a shell then you have to support cd.
  • cd是shell的属性,所以如果你要创建一个shell,那么你必须支持cd。

See it this way, when ls is executed then it needs to know the pwd. So, it your custom shell that would handle the directory. So, its the shell that has to support cd.

这样看,当执行ls然后它需要知道pwd。因此,它是您处理目录的自定义shell。所以,它的shell必须支持cd。

I think I made myself clear.

我想我已经说清楚了。