当在bash脚本中执行以下两行代码时,"ls"会抱怨文件不存在:
dirs=/content/{dev01,dev02} ls -l $dirs
当我使用-x选项运行脚本时,它似乎是在单引号内传递变量(这会阻止globbing):
+ dirs=/content/{dev01,dev01} + ls -l '/content/{dev01,dev01}' ls: /content/{dev01,dev01}: No such file or directory
如果我从交互式shell(无引号)执行"ls"命令,它将返回两个目录.
我一直在阅读Bash参考手册(第3.2版)并且看不到任何原因导致文件名通配不发生(我没有将-f传递给shell),或者我可以设置的任何东西以确保全球化发生了.
我认为这是扩展的顺序:
扩展的顺序是:
brace expansion
,波浪扩展,参数,variable
算术扩展和命令替换(以从左到右的方式完成),单词拆分和pathname expansion
.
因此,如果您的变量被替换,则不再进行大括号扩展.这对我有用:
eval ls $dirs
对eval要非常小心.它将逐字执行这些东西.因此,如果dirs包含f{m,k}t*; some_command
,则在ls完成后将执行some_command.它将执行您eval
在当前shell中提供的字符串.它将传递/content/dev01 /content/dev02
给ls,无论它们是否存在.把*
东西放到后面会使它成为路径名扩展,并且它将省略不存在的路径:
dirs=/content/{dev01,dev02}*
我对此并不是百分之百确定,但这对我来说很有意义.
以下是对您要做的事情的精彩讨论.
简短的回答是你想要一个数组:
dirs=(/content/{dev01,dev01})
但是你对结果所做的事情可能会比你想象的要复杂得多.
这不是文件夹通配,这是大括号扩展.区别是微妙的,但它存在 - 在文件名通配中你只会收到现有文件,而在大括号扩展中你可以生成任何类型的字符串.
http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion
http://www.gnu.org/software/bash/manual/bashref.html#Filename-Expansion
现在,这对我有用:
#!/bin/sh dirs=`echo ./{dev01,dev02}` ls $dirs
对于像我这样的人来说,可以通过Google找到它,@ Peter和@feoh的答案是“如何在bash脚本中全局变量”的通用解决方案。
list_of_results=(pattern)
会将现有匹配pattern
的文件名保存到数组中list_of_results
。的每个元素list_of_results
都包含一个文件名,空格和全部。
您可以访问每个结果作为"${list_of_results[
对
从0开始,您可以得到整个列表,正确引用,如"${list_of_results[@]}"
。