我读到在 Bash 中双引号所有变量扩展是最佳实践。我还读到不能*
在双引号变量扩展之后立即使用 shell glob (wildcard())。当人们想要使用从变量扩展出来的正则表达式模式的值时,这些情况就会发生冲突。
我有时想将正则表达式与通配符结合起来的原因是为了使我的正则表达式保持最小、更整洁,符合我的个人喜好。
我的特殊问题
我将 phpmyadmin 下载到我的文档根目录并解压缩,但我无法mv
通过我放入变量的正则表达式模式重命名它,并且在扩展其变量时可用。这是确切的跟踪:
userName@compName:/var/www/html# ll
total 11336
drwxr-xr-x 3 root root 4096 Feb 14 07:04 ./
drwxr-xr-x 3 root root 4096 Feb 14 06:56 ../
-rw-r--r-- 1 root root 612 Feb 14 06:57 index.nginx-debian.html
drwxr-xr-x 12 root root 4096 Dec 23 08:50 phpMyAdmin-4.7.7-all-languages/
-rw-r--r-- 1 root root 11589684 Dec 23 14:08 phpMyAdmin-latest-all-languages.zip
userName@compName:/var/www/html# echo $pma
[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]
userName@compName:/var/www/html# mv "$pma"*/ phpmyadmin/
mv: cannot stat '[pP][hH][pP][mM][yY][aA][dD][mM][iI][nN]*/': No such file or directory
如果我取消对变量扩展的引用,${pma}
我确实能够将变量扩展和正则表达式结合起来,如${pma}*
,但如果可以的话,毫无例外地遵循最佳实践对我来说很重要。
我的问题
我怎样才能保持变量扩展双引号,但仍然使用带通配符的提取值?
如果双引号,保存在变量中的文件名通配模式将不会通配文件名。阻止文件名被通配的是双引号,而不是
*
末尾的通配符或引号和*
.我们经常告诉网站上的用户“引用他们的变量”,我们这样做是因为未引用变量的值会经历分词和文件名通配,而这通常不是我们想要的。例如,根据当前目录中存在的文件(并且由于空间的原因,它可能根本无法正常工作) ,密码可能
[hello] world*
在命令行中包含会做“有趣”的事情。-p $password
另请参阅问题“忘记在 bash/POSIX shell 中引用变量的安全隐患”您在这里想要做的与我们通常想要避免的相反,即使用变量中的文件名通配模式调用文件名通配。
如果您确实不能依靠提取目录的名称来保持稳定,那么更好的(如“更清洁”)解决方案可能是确保它是临时目录中唯一的东西,然后只使用
*
移动它就位(可能在此过程中更改其名称,以便您确定它的名称)。这比简单地删除变量周围的引号要好,因为文件名通配模式可能会匹配您期望的单个名称之外的其他名称,具体取决于目录中可用的其他内容。
这是我对您上一个问题的回答的变体:
以上内容可归纳为五个步骤:
你不能1,你不想;没有它们,您的命令可以很好地工作(我很确定在这个问题的早期删除的变体之一中也指出了这一点)。
引用变量的目的是确保不会发生shell globbing和字段拆分。这次您实际上希望发生这种情况,因此引用会适得其反。
值得了解为什么存在这些准则;它们不是一揽子规则,如果它们不适合您,那么您可能会处于不适用的情况。在不理解它们的情况下努力“毫无例外地遵循最佳实践”是完全错误的。
除此之外,这个:
不是真的。
1你可以使用
eval
,但这完全没有意义,我不会再继续下去了。