为什么我无法将内容导入 cd?
例子:
$ pwd >> ~/mloc
$ cd /
$ tail -n 1 ~/mloc | cd
cd 失败。如果 do: cd $(tail -n 1 ~/mloc)
,则可行。
我知道我写的最后一个命令是有效的,但我不明白为什么我不能通过 cd 传输。
答案1
通过管道将数据发送给进程,代替你输入的内容后你已经启动了这个过程,不是您在启动该进程的命令中输入的内容。
(cd
也不是一个过程,但那不太重要,我在下面讨论它。)
管道附加一个命令的输出另一个命令的输入。 考虑:
foo | bar
运行bar
,运行foo
,并且:
- 它不在
foo
终端上显示输出,而是将其bar
作为输入。 - 代替服用输入至
bar
从终端foo
,它从的输出中获取。
(这两个要点实际上表达的是同一件事。)
那么,当你跑步时会发生什么tail -n 1 ~/mloc | cd
?
- 它运行
cd
,并且cd
在运行时只要接受输入,它就会从的输出中获取该输入tail -n 1 ~/mloc
。 cd
绝不运行时接受输入。
看标准流(维基百科)有关输入和输出在这个答案中。(这里,输入是指“标准输入”,输出是指“标准输出”。)
还有一个问题,它cd
实际上不是一个程序,而是一个 shell 内置程序,因此运行时cd
不会启动任何新进程。但那不是真的为什么你尝试的方法不起作用,因为:
正如您所尝试的那样,使用管道传递命令行参数对于任何程序来说都不起作用。
没有理由不能编写一个 shell 来容纳管道到shell 内置命令,考虑到它们可以容纳管道从shell 内建命令。
请注意,有时当你像使用真实程序一样使用 shell 内置命令时,实际运行的是同名的真实程序。但是没有单独的程序
cd
,我们可以通过管道从cd
;例如,运行cd blah 2>&1 | less
;如果blah
不存在或者不是目录,您将能够在中查看错误less
。
最后,考虑一下 的不同之处cd $(tail -n 1 ~/mloc)
。此命令:
- 运行
tail -n 1 ~/mloc
并捕获其输出。 - 不显示输出,而是构造一个由它附加到的命令组成
cd
。 - 运行该命令。
答案2
简短的回答是:cd 不是那样工作的。
http://www.gnu.org/software/bash/manual/bashref.html#index-cd
更详细的答案是,在 bash 中,管道中的命令都在子 shell 中执行。由于 cd 是 shell 内置命令,因此它只会影响执行它的 shell。如果您在子 shell 中执行 cd,则效果会在子 shell 退出时消失。