Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash如何处理不匹配的通配符?_Bash_Wildcard - Fatal编程技术网

bash如何处理不匹配的通配符?

bash如何处理不匹配的通配符?,bash,wildcard,Bash,Wildcard,我学习了bash,使用通配符遇到了下一个问题: sergs:~ > ls -1 a.sh Desktop Downloads eclipse sergs:~ > a=*.sh sergs:~ > echo $a a.sh sergs:~ > a=*.sha sergs:~ > echo $a *.sha 如果没有与*.sha模式匹配的文件,为什么bash会返回模式本身而不是什么都没有 因此,行为打破了这种逻辑: for i in /usr/lib/opkg/inf

我学习了bash,使用通配符遇到了下一个问题:

sergs:~ > ls -1
a.sh
Desktop
Downloads
eclipse
sergs:~ > a=*.sh
sergs:~ > echo $a
a.sh
sergs:~ > a=*.sha
sergs:~ > echo $a
*.sha
如果没有与
*.sha
模式匹配的文件,为什么
bash
会返回模式本身而不是什么都没有

因此,行为打破了这种逻辑:

for i in /usr/lib/opkg/info/*.postinst; do do_some_logic_with_postinst_file; done

我是否必须检查
/usr/lib/opkg/info/
目录是否没有任何
*。postinst
文件,除非打开展开的shell选项
nullglob
,如果glob展开失败,该选项将不返回任何结果,否则将在命令行中直接返回未展开的glob字符串

不过,对于您的用例来说,通过测试glob扩展是否成功,以查看扩展结果是否为文件(即

for file in /usr/lib/opkg/info/*.postinst; do 
    [ -f "$file" ] || continue
    do_some_logic_with_postinst_file
done
条件
[-f“$file”]
将检查您的全局扩展是否正确,即是否存在任何
。postinst
文件
[-f“$file”]
是否正确。对于未扩展的glob,条件

[ -f /usr/lib/opkg/info/*.postinst ] 
将失败,因为文本字符串
/usr/lib/opkg/info/*.postinst
不是有效的文件,并且此
test
命令与布尔或
|
一起失败会导致
continue
操作转到
for
循环。由于
for
循环没有更多的参数要处理,因此该循环会正常退出

这样做(针对glob字符串使用
-f
)保证符合POSIX。但是,对于
bash
特定的答案,您可以打开前面提到的选项

# '-s' enables the option
shopt -s nullglob

for file in /usr/lib/opkg/info/*.postinst; do 
    do_some_logic_with_postinst_file
done

# '-u' disables the option
shopt -u nullglob
一旦您决定使用
nullglob
选项,就有很多方法可以使用它来运行您的功能。例如,您可以将所有glob结果放入数组类型中,并检查长度是否有效

shopt -s nullglob
results=(/usr/lib/opkg/info/*.postinst)

if (( ${#results[@]} )); then
    printf '%s\n' 'my array is not empty'
    for file in "${results[@]}"; do
        printf '%s\n' "some action on ${file}"
    done
fi

shopt -u nullglob
当不使用
nullglob
选项时,请小心此方法。如果没有相同的设置,
results=(/usr/lib/opkg/info/*.postinst)
部分仍然可以是非空的,因为文本字符串仍然存储在数组中

OP的另一个小补充是,永远不要使用变量来保存全局字符串。因为当变量展开时,如果glob展开成功,则变量的内容将由shell进行分词,并且包含空格的文件名可能会被分解为多个条目,而您不希望这样做


始终使用数组和适当的引号扩展。有关此主题的详细信息,请参阅。

这就是glob模式的工作原理(编辑:除非您像Inian指出的那样启用
nullglob
)。另一种选择是

读取文件时查找/usr/lib/opkg/info-name\*.postinst;做 #使用postinst文件执行一些逻辑操作 完成```
我很想将其作为的副本关闭,但Q需要解释shell如何处理未展开的glob字符串