如果我运行以下命令替换脚本:
var=$(ls)
echo $var
它按预期工作——输出是ls
命令的结果。但如果我使用 read 分配变量:
read var
echo $var
其中 $(ls) 是 的输入read
,输出是文字
$(ls)
而不是命令的输出ls
。
我不明白为什么会有这样的差异,因为我认为变量的内容var
在两种情况下应该相同,因此 shell 应该echo
以完全相同的方式处理命令。
你能解释一下吗?
答案1
命令替换是 shell 扩展,Bash 不会对输入进行扩展read
。
这是一件好事,因为read
它可以捕捉到天真的(或专家的)用户输入的任何废话(或精彩内容)。
尝试输入 shell 通常会扩展的任何输入,你会发现同样的事情发生了......
$ var=~ # ~ was expanded before assignment
$ echo $var
/home/zanna
$ read -r var
~
$ echo $var
~
有一些例外 -read
将反斜杠字符视为转义符
反斜杠字符“\”可用于删除读取的下一个字符和行继续的任何特殊含义。
这几乎从来不是你真正想要的(你想read
捕捉无论用户输入什么包括任何反斜杠),因此您应该习惯性地使用-r
带有标志的符号read
(就像我在示例中所做的那样):
-r
如果指定此选项,反斜杠将不充当转义字符。反斜杠被视为行的一部分。特别是,反斜杠-换行符对不能用作行延续。
另一个例外是,输入以类似于分词的方式拆分为字段,因此您可以分配给多个变量:
$ read -r var
one two three
$ echo $var
one two three
$ read -r baa ram ewe
one two three
$ echo $ram
two
引言来自本节Bash 手册 - 向下滚动查找read
,或者help read
在 shell 中运行以获取较短的版本。
答案2
var=$(ls)
执行命令 ls 并将输出赋值给变量 在第二种情况下,它只是将您输入的字符串赋值给变量,没有执行任何操作。它只是将字符串赋值给变量,bash 不会对其执行任何操作。