从文件中读取的字符串中的大括号,没有扩展

时间:2014-12-18 07:41:58

标签: bash

我的情况是我有一个名为'file.txt'的文件,它是一堆文件的列表,如下所示:

/path/{a,b,c}/file.d
/path/file.e
/path/file.f

然后我写了一个包含从这个文件中读取循环的bash文件:

#!/bin/bash
while read line; do ls -alh $line;done < file.txt

我发现它不能像我想的那样工作,支撑扩展在这种情况下不起作用,所以我想知道是否有工作或bash中的某些东西?

2 个答案:

答案 0 :(得分:3)

Bash首先扩展大括号,然后扩展变量。这是一个更简单的例子:

$ a="/path/{a,b,c}"
$ echo $a
/path/{a,b,c}
$ eval 'echo $a'
/path/{a,b,c}
$ eval "echo $a"
/path/a /path/b /path/c

您需要使用eval强制执行第二次评估。

但是在使用eval时请仔细检查输入。你不希望有人在你的文件的某一行写下“虚拟; dobadthings”这样的东西......

答案 1 :(得分:2)

在这种特殊情况下,我根本不会使用大括号扩展。无论如何,这不是正确的工具。并且使其工作的唯一解决方法是以危险的方式使用eval - 不仅因为潜在的恶意用户,而且仅仅因为文件名中可能会有一些特殊字符被这样做误解。

这项工作的正确工具是使用shell globs with pattern matching

这可以让你走上正轨:

#!/bin/bash
shopt -s extglob
while IFS= read -r line; do
    ls -alh -- $line
done < file.txt

将您的文件file.txt写为:

/path/@(a|b|c)/file.d
/path/file.e
/path/file.f

您将能够以安全的方式使用*?,角色类,+(...)!(...) 等精美内容