在bash shell中,我想在完整路径下列出$ folder(我的代码中的变量名)下的文件名.
但是,如果我这样编码,
dir $folder"*"
Run Code Online (Sandbox Code Playgroud)
它输出错误
"dir: cannot access <folder_name> : No such file or directory"
Run Code Online (Sandbox Code Playgroud)
如果我更改这样的代码,它的工作原理,
search_str=$folder"*"
dir $search_str
Run Code Online (Sandbox Code Playgroud)
似乎连接到dir命令的字符串不是我想要的,如果我将字符串存储在一个变量中并将其传递给dir命令就可以了.
任何人都知道原因以及如何使用search_str?
注意:我在下面的示例中使用标准的Unix实用程序ls而不是GNU特定的实用程序dir(谢谢,hek2mgl),因为该问题与通用shell行为有关,并不仅限于具有GNU实用程序的平台.
TL;博士
ls "$folder"* # double-quote the var. reference, use * unquoted
Run Code Online (Sandbox Code Playgroud)
模式(globbing)元字符*必须使用不带引号才能被识别.
因此,ls $folder"*"总是不会按预期工作,因为你(双)引用 *.
相比之下,变量赋值search_str=$folder"*"会导致*附加到$folder(作为文字的值,因为它是双引号,但最终没有引号,因为shell在字符串连接的过程中删除双引号,因为它们具有句法意思而不是文字 ;这种删除恰当地称为引用删除).
它是命令中变量的无引号使用ls $search_str,然后使*有效作为通配符(模式元字符).
然而,这种不带引号的使用可变的本质上是不稳健的,因为价值$search_str是作为一个整体不仅受到通配符,也给词分裂,这意味着,如果原来的命令将打破$folder变量中包含有路径嵌入式空间.
因此,当实际需要通配时,最好附加* 按需:
ls "$folder"*
Run Code Online (Sandbox Code Playgroud)
注意如何*不引用 - 使其作为模式元字符有效 - 而"$folder"有意地双引号 - 以确保它按原样使用(分词和通配不应用于其值).