我了解到 shell 扩展了某些类型的字符。这就是为什么在写作时:
$ echo *
我得到目录和文件的列表,假设我得到:
Applications Desktop Documents
现在,假设我写
$ foo=Applications Desktop Documents
我得到:
-bash: Desktop: command not found
很好,但是写的时候:
$ foo=*
那行得通,为什么呢?我确信 * 应该扩展并给出与上面相同的错误。
写作时
$ echo ${#foo}
我得到答案 1,这表明 * 已保存到 foo
为什么 * 没有在作业中扩展?当我写作时它确实会扩展
$ echo ${foo}
谢谢
答案1
变量赋值期间不会发生路径名扩展。以下是 bash 联机帮助页的摘录:
如果未给出值,则为该变量分配空字符串。所有值都会经历波形符扩展、参数和变量扩展、命令替换、算术扩展和引号删除(请参阅下面的扩展)。如果变量设置了整数属性,则即使未使用 $((...)) 扩展,值也会被计算为算术表达式(请参阅下面的算术扩展)。不执行分词,“$@”除外,如下特殊参数中所述。不执行路径名扩展。
当您执行 的赋值时foo=*
, foo 变量将包含一个文字*
。当您稍后使用变量(不带引号)时,参数首先扩展为文字*
,然后发生路径名扩展。您可以*
通过引用参数扩展来验证它是否包含文字:
$ foo=*
$ echo "$foo"
*
bash 中此规则有一些例外,例如在分配数组时:
$ foo=(*)
在上面的示例中,路径名扩展立即发生,并且数组包含与 glob 匹配的文件列表。
答案2
如果 shell 无法将通配符扩展为 glob,则按字面处理:
$ cd scratch
$ rm *
$ foo=*
$ echo $foo
*
$ echo "$foo"
*
$ touch file
$ echo $foo
file
$ echo "$foo"
*