我尝试了以下命令
variable='one|name'
echo $variable
输出是
one|name
而echo one|name
给出了一个错误No command 'name' found
。这是合理的,因为 bash 将其|
视为管道并尝试将命令name
作为one
输入来执行。
但为什么会echo $variable
打印呢one|name
?参数和变量展开后,不应该等价于 吗echo one|name
?
版本:
GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)
答案1
不,不应该,因为方式bash
操作命令。
当您键入 时echo one|name
,bash
解析命令,将其|
视为管道令牌,因此|
执行管道。
当您键入 时echo $variable
,由于标记解析发生在变量扩展之前,因此bash
将命令解析为两部分,echo
和$variable
。之后,它执行变量扩展,扩展$variable
为one|name
.在这种情况下,one|name
是一个字符串,|
是字符串的一部分,不能被视为管道令牌(当然,令牌识别短语已完成)。如果IFS
变量包含|
,唯一可以特殊的事情bash
将用作|
分隔符来执行字段拆分:
$ variable='one|name'
$ IFS='|'
$ echo $variable
one name
答案2
原因是因为Bash
变量扩展的方式。
不是将变量扩展为 ,而是one|name
将变量扩展为"one|name"
。因此,这里由于值括在引号内,因此它们被视为字符串而不是命令。
下面是strace
命令的输出,显示了命令如何扩展。
$ variable='one|name'
$ strace echo $variable
execve("/bin/echo", ["echo", "one|name"], [/* 33 vars */]) = 0
brk(0) = 0x9cc7000
答案3
引号是您创建的字符串的一部分。
如果你这样做了
variable=one|name
echo $variable
结果将如预期。但您只能在脚本中执行此操作(感谢您的有用评论)。