当前位置:  开发笔记 > 编程语言 > 正文

如何在Bash脚本中为一个变量赋一个glob表达式?

如何解决《如何在Bash脚本中为一个变量赋一个glob表达式?》经验,为你挑选了4个好方法。

当在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),或者我可以设置的任何东西以确保全球化发生了.



1> Johannes Sch..:

我认为这是扩展的顺序:

扩展的顺序是: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}*

我对此并不是百分之百确定,但这对我来说很有意义.



2> feoh..:

以下是对您要做的事情的精彩讨论.

简短的回答是你想要一个数组:

dirs=(/content/{dev01,dev01})

但是你对结果所做的事情可能会比你想象的要复杂得多.


你必须做ls"$ {dirs [@]}".但它会在分配时将名称扩展为dirs.所以dirs实际上会包含文件名,而不仅仅是模式
链接已死。下次请引用与您相关的部分,这对每个人来说都将更加容易。

3> Yoni Roit..:

这不是文件夹通配,这是大括号扩展.区别是微妙的,但它存在 - 在文件名通配中你只会收到现有文件,而在大括号扩展中你可以生成任何类型的字符串.

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



4> cxw..:

对于像我这样的人来说,可以通过Google找到它,@ Peter和@feoh的答案是“如何在bash脚本中全局变量”的通用解决方案。

list_of_results=(pattern)

会将现有匹配pattern的文件名保存到数组中list_of_results。的每个元素list_of_results都包含一个文件名,空格和全部。

您可以访问每个结果作为"${list_of_results[]}"从0开始,您可以得到整个列表,正确引用,如"${list_of_results[@]}"

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有