cd 命令在管道中的行为

Tor*_*edo 6 unix linux bash

我的问题是当 cd 位于管道的开头或中间时,为什么 cd 的行为方式与 bash 的行为方式相同。

当我给 cd | ls,它仍然打印父目录中的文件,基本上有效,它忽略了cd命令。

为什么在 csh 中没有以这种方式实现: 当我给 cd | ls,它应该 cd 到 home 目录并在该目录上应用 ls。当控制权返回给 shell 时,它应该保留 shell 运行时使用的 pwd 的旧值。即管道中的 cd 应该对 cd 命令右侧的所有命令使用更改后的目录。

我在这里错过了一些基本的设计原则吗?

djn*_*jna 7

您确实缺少一个基本的设计原则。

通常,当您启动一个进程时,它有自己的“环境”,包括所有环境变量和当前工作目录。进程所做的任何更改仅限于该进程及其子进程。这实际上是非常可取的,想象一下如果过程可能影响他们的兄弟姐妹,甚至更糟的是他们的父母,可能会发生混乱。

当你有管道时,你就有了一个父级,你在其中指定了一个管道的 shell 和许多子级都“管道”在一起,每个子级都有一个独立的环境。

一旦你理解了这一点,就很容易解决问题并更改父目录中的目录。

  (cd /etc && ( ls | grep x))
Run Code Online (Sandbox Code Playgroud)

这里整个事情都在 () 中,因此它在子进程中运行,因此 cd 不会影响当前的 shell,但会影响在(大)子进程中运行的管道。

  • && 并没有真正创建管道,当我们使用 | 我们将一个孩子的输出连接到下一个孩子的输入,这是基本的“管道”比喻。使用 && 我们正在执行一个动作,然后执行另一个动作,但**仅**如果第一个有效。在这种情况下,我们尝试使用 cd 并且仅当它有效(目标目录存在)时,我们才尝试使用流水线命令。 (2认同)

小智 2

因为这不是管道的用途。它们用于指导输入/输出,而不是控制 shell 的状态。

如果您想要所描述的行为,请使用子 shell:

( cd ; ls )
Run Code Online (Sandbox Code Playgroud)