我试图检查一个文件是否存在,但与通配符。以下是我的例子:
if [ -f "xorg-x11-fonts*" ]; then
printf "BLAH"
fi
我也试过不加双引号。
我试图检查一个文件是否存在,但与通配符。以下是我的例子:
if [ -f "xorg-x11-fonts*" ]; then
printf "BLAH"
fi
我也试过不加双引号。
当前回答
如果您的shell有一个nullglob选项,并且该选项被打开,则不匹配任何文件的通配符模式将从命令行中完全删除。这将使ls看不到任何pathname参数,列出当前目录的内容并成功,这是错误的。如果没有参数或参数命名了一个不存在的文件,GNU stat总是会失败,它将更加健壮。另外,&>重定向操作符是bashism。
if stat --printf='' /path/to/your/files* 2>/dev/null
then
echo found
else
echo not found
fi
更好的是GNU find,它可以在内部处理通配符搜索,并在找到一个匹配文件时立即退出,而不是浪费时间处理由shell扩展的潜在的巨大列表;这也避免了shell可能溢出其命令行缓冲区的风险。
if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"
then
echo found
else
echo not found
fi
非gnu版本的find可能没有此处使用的-maxdepth选项,以使find只搜索/dir/to/search,而不是整个目录树。
其他回答
Use:
if [ "`echo xorg-x11-fonts*`" != "xorg-x11-fonts*" ]; then
printf "BLAH"
fi
我使用的Bash代码:
if ls /syslog/*.log > /dev/null 2>&1; then
echo "Log files are present in /syslog/;
fi
恕我直言,最好在测试文件、glob或目录时使用find always。这样做的绊脚石是find的退出状态:如果成功遍历所有路径,则为0,否则为>。传递给find的表达式在退出代码中没有创建回显。
下面的示例测试目录是否有条目:
$ mkdir A
$ touch A/b
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . && echo 'not empty'
not empty
当A没有文件时,grep失败:
$ rm A/b
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . || echo 'empty'
empty
当A不存在时,grep再次失败,因为查找只打印到stderr:
$ rmdir A
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . && echo 'not empty' || echo 'empty'
find: 'A': No such file or directory
empty
用其他find表达式替换-not -empty,但如果-exec命令打印到stdout,请小心。在这种情况下,您可能需要使用grep来获得更具体的表达式。
这种方法在shell脚本中工作得很好。最初的问题是寻找glob xorg-x11-fonts*:
if find -maxdepth 0 -name 'xorg-x11-fonts*' -print | head -n1 | grep -q .
then
: the glob matched
else
: ...not
fi
注意,如果xorg-x11-fonts*没有匹配,或者find遇到错误,就会到达else-branched。使用$?来区分大小写。
严格来说,如果你只想打印“Blah”,下面是解决方案:
find . -maxdepth 1 -name 'xorg-x11-fonts*' -printf 'BLAH' -quit
这里有另一种方法:
doesFirstFileExist(){
test -e "$1"
}
if doesFirstFileExist xorg-x11-fonts*
then printf "BLAH"
fi
但我认为最优的是如下所示,因为它不会尝试对文件名进行排序:
if [ -z $(find . -maxdepth 1 -name 'xorg-x11-fonts*' -printf 1 -quit) ]
then
printf "BLAH"
fi
如果您的shell有一个nullglob选项,并且该选项被打开,则不匹配任何文件的通配符模式将从命令行中完全删除。这将使ls看不到任何pathname参数,列出当前目录的内容并成功,这是错误的。如果没有参数或参数命名了一个不存在的文件,GNU stat总是会失败,它将更加健壮。另外,&>重定向操作符是bashism。
if stat --printf='' /path/to/your/files* 2>/dev/null
then
echo found
else
echo not found
fi
更好的是GNU find,它可以在内部处理通配符搜索,并在找到一个匹配文件时立即退出,而不是浪费时间处理由shell扩展的潜在的巨大列表;这也避免了shell可能溢出其命令行缓冲区的风险。
if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"
then
echo found
else
echo not found
fi
非gnu版本的find可能没有此处使用的-maxdepth选项,以使find只搜索/dir/to/search,而不是整个目录树。