我试图cd
接受从另一个命令重定向到它的目录名称。这些方法都不起作用:
$ echo $HOME | cd
$ echo $HOME | xargs cd
这确实有效:
$ cd $(echo $HOME)
为什么第一组命令不起作用,还有其他命令也会失败吗?
我试图cd
接受从另一个命令重定向到它的目录名称。这些方法都不起作用:
$ echo $HOME | cd
$ echo $HOME | xargs cd
这确实有效:
$ cd $(echo $HOME)
为什么第一组命令不起作用,还有其他命令也会失败吗?
Answers:
cd
不是外部命令-它是Shell内置函数。它在当前shell的上下文中运行,而不像外部命令那样在fork / exec的上下文中作为单独的进程运行。
您的第三个示例可行,因为shell在调用cd
内置函数之前先扩展变量和命令替换,以便cd
接收值${HOME}
作为其参数。
POSIX系统确实有一个二进制文件cd
-在我的FreeBSD机器上,它位于/usr/bin/cd
,但没有按照您的想法运行。调用二进制文件cd
会导致外壳派生/执行该二进制文件,这确实会将其工作目录更改为您传递的名称。但是,一旦这样做,二进制文件就会退出,并且分叉/执行的进程会消失,将您带回到您的shell,该shell仍位于开始之前的目录中。
cd
命令的作用是什么?
除了现有的良好答案外,还值得一提的是,管道派生了一个新进程,该进程具有自己的单独工作目录。因此,尝试执行此操作将无效:
echo test | cd /
因此,shell从此命令返回后,您将不在/文件夹中。
a | b
,即使a
和b
都是内置的,也至少有一个命令不会在shell进程中运行,但是不能保证它是哪一个。例如,在AT&T ksh
中zsh
或中bash -O lastpipe
,b
是在当前Shell进程中运行的,因此您的代码会将您带到/那里。
除了已经给出的正确答案之外:如果您运行bash并想找出cd之类的“命令”,则可以使用type
$ type cd
cd is a shell builtin
或为什么不:
$ type time
time is a shell keyword
而例如,通常您喜欢的发行版中已经包含了gnu time:
$ which time
/usr/bin/time
好的,您知道了,那么到底是什么类型?
$ type type
type is a shell builtin
这是bash手册片段:
type [-aftpP] name [name ...]
With no options, indicate how each name would be interpreted if used as a
command name. If the -t option is used, type prints a string which is one of
alias, keyword, function, builtin, or file if name is an alias, shell
reserved word, function, builtin, or disk file, respectively. If the name is
not found, then nothing is printed, and an exit status of false is returned.
If the -p option is used, type either returns the name of the disk file that
would be executed if name were specified as a command name, or nothing if
‘‘type -t name’’ would not return file. The -P option forces a PATH search
for each name, even if ‘‘type -t name’’ would not return file. If a command
is hashed, -p and -P print the hashed value, not necessarily the file that
appears first in PATH. If the -a option is used, type prints all of the
places that contain an executable named name. This includes aliases and
functions, if and only if the -p option is not also used. The table of
hashed commands is not consulted when using -a. The -f option suppresses
shell function lookup, as with the command builtin. type returns true if any
of the arguments are found, false if none are found.
就像其他人所说的那样,它cd
是行不通的,因为它是Shell内置命令,而不是外部程序,因此它没有任何标准输入,您可以将任何内容输入其中。
但是,即使它起作用了,也无法满足您的期望:管道产生了一个新进程,并将第一个命令的标准输出重定向到第二个命令的标准输入,因此只有新进程才能更改其当前的工作状态目录; 这不会以任何方式影响第一个过程。
read
通常是(总是?)内置的shell。确实可以cd
忽略stdin,但这不是由于它是内置函数。
另一个选择是反引号,它会将一个命令的标准输出作为第二个命令的命令行参数,并且比更具可移植性$(...)
。例如:
cd `echo $HOME`
或更一般地;
cd `anycommand -and whatever args`
请注意,反引号的使用取决于用于执行命令并替换命令行上的输出的外壳。大多数shell支持它。
$(...)
在一个系统上支持但在另一个系统上不支持吗?
$(…)
。没有POSIX外壳(即具有纯正的Bourne外壳)的系统将非常旧。如今,即使/bin/sh
是Bourne Shell且您需要另一条路径(例如/usr/xpg4/bin/sh
获得POSIX Shell)的系统也很少见。向没有专业管理古代Unix Boxen的人推荐反引号对他们来说是一种伤害。