以下命令似乎大致相同:
read varname
varname=$(head -1)
varname=$(sed 1q)
一个区别是while和are 不是read
内置的 shell 。head
sed
除此之外,三者之间的行为有什么不同吗?
我的动机是更好地理解 shell 和关键实用程序(例如head,sed
.例如,如果 usinghead
可以轻松替代read
,那么为什么read
它作为内置函数存在呢?
答案1
效率和内置性都不是最大的区别。对于某些输入,它们都会返回不同的输出。
head -n1
仅当输入有换行符时才会提供尾随换行符。sed 1q
将始终提供尾随换行符,但否则保留输入。read
永远不会提供尾随换行符,并且会解释反斜杠序列。
此外,read
还有其他选项,例如拆分、超时和输入历史记录,其中一些是标准的,另一些则因 shell 而异。
答案2
一方面,您可以使用 read 来解析文本,而不仅仅是读取整行
echo "foo:bar:baz" | {
IFS=: read one two three
echo $two
}
答案3
内置函数的存在是为了让系统调用更快。因此,我相信read
命令作为内置命令存在是为了更加高效。
引用自这里,
这些内置命令是 shell 的一部分,并作为 shell 源代码的一部分实现。 shell 认识到要求它执行的命令是其内置命令之一,并且它自行执行该操作,而无需调用单独的可执行文件。不同的 shell 有不同的内置函数,尽管基本集合中会有很多重叠。
现在,我希望您自己对此进行实验,以便您可以理解为什么read
它作为 shell 内置命令存在。
通常,您无法strace
在 shell 内置函数上执行此操作。不过,也有一个解决方法。这在this中解释得很清楚回答。
- 在第一个 shell 中,运行命令为
stty -echo
. - 打开另一个 shell 并将命令运行为
cat | strace bash > /dev/null
. - 现在,shell 将等待用户输入命令,当用户输入命令时,您也可以看到系统级别发生的情况。
- 当您给出上述 3 个命令时,您可以看到 read 的系统调用比其余 2 个命令少。我不会粘贴输出,
strace
因为它很大。
答案4
varname
您可以在 shell 脚本中使用 read only,但其他两个则可以在不编写 shell 脚本的情况下使用。
例如:
您可以在终端中使用varname=$(head -1)
and简单地作为命令,但您还必须提供您的参数,即您所引用的最上面一行文件,即。varname=$(sed 1q)
varnam=$(head -1 file1)