在bash shell中,我想在完整路径下列出$ folder(我的代码中的变量名)下的文件名。
但是,如果我这样编码,
dir $folder"*"
输出错误
"dir: cannot access <folder_name> : No such file or directory"
如果我更改这样的代码
,它会起作用search_str=$folder"*"
dir $search_str
似乎连接到dir命令的字符串不是我想要的,如果我将字符串存储在一个变量中并将其传递给dir命令就可以了。
任何人都知道原因&amp;怎么不使用search_str?
答案 0 :(得分:5)
注意:我在下面的示例中使用的是标准Unix实用程序ls
而不是GNU-specific utility dir
(感谢hek2mgl),因为该问题与通用shell行为和不仅限于具有 GNU 实用程序的平台。
<强> TL;博士强>
ls "$folder"* # double-quote the var. reference, use * unquoted
*
等模式(全局)元字符必须使用不加引号 才能被识别。
因此,ls $folder"*"
总是不按预期工作,因为您(双 - )引用了 *
。
相比之下,变量赋值search_str=$folder"*"
会将*
附加到$folder
的值(作为文字,因为它是双引号,但最终没有引号,因为shell在字符串连接过程中删除了双引号,因为它们具有语法含义而不是文字;这种删除被恰当地调用引用删除)。
命令ls $search_str
中变量的未加引号的使用然后使*
有效作为通配符(模式元字符)。
然而,未加引号使用变量本质上是不健全 ,因为$search_str
的值整体不仅要使用globbing,还要使用分词,这意味着如果原始$folder
变量包含带有嵌入空格的路径,命令将会中断。
因此,当实际需要使用globbing时,最好追加*
按需:
ls "$folder"*
请注意*
未加引号的方式 - 使其作为模式元字符有效 - 而"$folder"
有意双引号 - 以确保将用作 -is (分词和globbing不应用于其值)。
答案 1 :(得分:0)
假设$ folder是tmp
dir $ folder&#34; *&#34;相当于dir tmp*
而在下面
的情况下search_str=$folder"*"
dir $search_str
$ search_str相当于dir temp
当您使用双引号时,需要额外的步骤才能展开。详细了解shell中的变量扩展
答案 2 :(得分:0)
虽然@ mklement0的答案解释了错误的原因,但您也可以寻找其他可能的解决方案。首先让我借用另一个回答下面的行
模式(globbing)元字符如*必须在未引用的情况下使用 为了得到承认。
案例1:如果您希望在文件夹中递归列出(不是解析,只列出)文件(仅限文件),请使用[ globstar ]。
shopt -s globstar
folder="yourfoldername**"
ls -p $folder | grep -v '/$' #mind that '$folder' is not inside double quotes
# '-p' adds trailing slash to directories and we neglect those results using grep invert match
# Here I inadvertantly parsed the `ls` output, see the link in case 2 for why you shouldn't do that.
案例2:如果您希望在文件夹中递归地解析(不仅仅是列出)文件(仅文件),请使用find
作为ls
输出无法解析 [Check this]
folder="yourfoldername" #no trailing **
find "$folder" -type f -print0 | while read -r -d '' fname
do
#do something with "$fname"
done