如何防止在通过冒号分割冒号分离的glob模式时扩展glob模式?

时间:2015-08-18 03:37:55

标签: shell posix glob

这是我为POSIX shell编写的shell脚本。我的目标是POSIX shell兼容性。有一个PATTERNS变量,包含冒号分隔的glob模式。此变量是用户输入。我无法改变这一点。代码的其余部分是我的代码,我可以更改它以实现我的目的。下面的小型演示程序的目的是在一个单独的行上记录(或显示)每个glob模式。

PATTERNS=*.*:*.txt:*.html
IFS=:
for pattern in $PATTERNS
do
    unset IFS
    echo Pattern: "$pattern"
done

这是当前的工作目录。

$ ls
a.txt  b.txt  foo.sh

当我运行代码时,我得到了这个输出。

$ sh foo.sh 
Pattern: a.txt
Pattern: b.txt
Pattern: foo.sh
Pattern: a.txt
Pattern: b.txt
Pattern: *.html

它不是在一行中显示每个glob模式,而是显示一行中由glob模式匹配的每个文件。由于*.html与当前目录中的任何文件都不匹配,因此只显示了这个glob模式。

我想要的输出是:

Pattern: *.*
Pattern: *.txt
Pattern: *.html

所以我希望glob模式不会扩展到当前目录中的文件名。我怎样才能做到这一点?解决方案必须适用于任何POSIX shell。

1 个答案:

答案 0 :(得分:0)

不是肯定的我没有错过任何东西,或者没有更好的方法,但这种方法并没有使用我所知道的任何不可移植的东西。

#!/bin/sh

PAT="*.rc:*.rpms:*.sh"

# Function so we can repeatedly expand the remaining string.
read_next() {
    IFS=: read hd tl <<EOF
$1
EOF
}

tl=$PAT
while read_next "$tl" && [ -n "$hd" ]; do
    echo "Pattern: $hd"
done

或者,这更简单,但它需要“全局”IFS修改,我从来不喜欢(我更喜欢IFS上的范围read修改)以及修改全局shell设置,您只需使用-f标记完全禁用路径名扩展到set(然后根据需要使用set +f重新启用它)然后保留原始设置循环。