Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.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
为什么Perl';当给定一个没有全局字符的字符串时,s glob()函数是否总是返回一个文件名?_Perl_Glob - Fatal编程技术网

为什么Perl';当给定一个没有全局字符的字符串时,s glob()函数是否总是返回一个文件名?

为什么Perl';当给定一个没有全局字符的字符串时,s glob()函数是否总是返回一个文件名?,perl,glob,Perl,Glob,我给Perl的glob函数提供了一个glob列表和一个字符串。glob按预期处理,但始终找到字符串。例如: $ ls foo $ perl -le '@files=glob("*bar"); print @files' ## prints nothing, as expected $ perl -le '@files=glob("bar"); print @files' bar 如上所示,第二个示例打印条,即使不存在这样的文件 我的第一个想法是,它的行为类似于shell,当没有可用的扩展时,g

我给Perl的
glob
函数提供了一个glob列表和一个字符串。glob按预期处理,但始终找到字符串。例如:

$ ls
foo
$ perl -le '@files=glob("*bar"); print @files' ## prints nothing, as expected
$ perl -le '@files=glob("bar"); print @files'
bar
如上所示,第二个示例打印
,即使不存在这样的文件

我的第一个想法是,它的行为类似于shell,当没有可用的扩展时,glob(或被视为glob的东西)会扩展到自身。例如,在
csh
中(虽然很糟糕,但这就是Perl的
glob()
函数的作用,请参见下面的引文):

但是,根据,
glob
应该返回文件名扩展名(emphasis mine):

在列表上下文中,返回EXPR值上的文件名扩展的列表(可能为空),如标准的unixshell/bin/csh


那么,当传递给
glob
的参数中没有globbing字符时,为什么它会返回自身呢?这是一个bug还是我做错了什么?

当您使用
*
[]
时,只会返回现有的文件或目录。当您的模式只有文本或
{}
时,将返回所有可能的结果。这完全符合csh的功能

通常,人们会因此而做
@results=grep-e,glob-PATTERN

或者,如果您希望对此进行更多控制,也可以使用。(请注意,这样做没有额外的开销;因为在使用glob()时,perl会悄悄地加载File::glob并使用它。)

我想我希望Perl在后台检查文件是否存在

Perl正在检查文件是否存在:

$strace perl-e'glob“foo”2>&1|grep foo
execve(“/home/mcarey/perl5/perlbrew/perls/5.24.0-debug/bin/perl”、[“perl”、“-eglob\“foo\”]、[/*39 vars*/])=0
lstat(“foo”,{st_mode=S_IFREG | 0664,st_size=0,…})=0

那么,当传递给glob的参数中没有globbing字符时,为什么它会返回自身呢

因为csh就是这么做的。Perl对
glob
的实现基于启用了
glob\u nomatic
标志:

全球游牧

与GLOB_NOCHECK相同,但它仅在不包含任何特殊字符
*
[
时附加模式。提供GLOB_nomacic是为了简化实现历史csh(1)全局行为,可能不应在其他任何地方使用

GLOB\u NOCHECK

如果模式与任何路径名都不匹配,则glob()返回一个仅包含模式的列表

因此,对于像
foo
这样没有通配符的模式:

  • 如果存在匹配的文件,则返回文件扩展名(
    foo
  • 如果不存在匹配的文件,则返回模式(
    foo
由于文件名扩展与模式相同

glob 'foo'

在列表上下文中,无论文件
foo
是否存在,都将始终返回包含单个元素
foo
的列表。

为什么要传递单个常量值(没有通配符)对于
glob
这样的问题?@toolic使我的问题保持简单。实际的用例稍微复杂一些。在我的脚本中,我传递了一个数组,如
(“*foo”、“*bar”、“string”)
,所以各种glob和一个确切的文件名。我可以想到各种解决方法,但我很好奇为什么
glob()
仅在简单字符串上的行为类似于此。这很挑剔,但
“*bar”
“bar”
都是字符串。您的意思是“为什么Perl的glob()函数在给定一个不带通配符的字符串而不是带通配符的字符串时总是返回文件名?”@这还不够公平,glob毕竟是glob。某个东西是字符串还是glob取决于使用它的上下文。显然,它在这里被用作简单字符串而不是glob,所以我这样称呼它。但你是对的,我可以更精确一些。“bar”已完全展开并作为文件名有效。只有在添加通配符时,系统才需要查看文件系统以查找匹配项。很公平,谢谢。我现在找到了相关的POSIX部分,我应该首先检查它。我想我希望Perl会在后台检查文件是否存在。我确认bash不会如果你想避免这种行为,你需要在
文件::GLOB::bsd_GLOB
中使用
GLOB_BRACE
选项@terdon POSIX sh文件名扩展不同于perl所做的(它没有{}支持,如果没有与
*
[]
匹配的文件名,它会返回模式);正如您引用的perl文档中提到的,perl正在尝试与csh兼容(我找不到好的链接)@CasimiritHippolyte实际上,如果没有匹配项,bash返回模式,即使它包含通配符,这与csh不同:
echo f*;touch foo;echo f*
。您可以通过设置
failglob
。使用File::Glob,您可以使用
Glob\u NOCHECK
Glob\u NOMAGIC
@ysth来控制此行为,没错。我一直试图忘记csh。顺便说一句,很抱歉这个不可接受的问题,但是另一个答案给出了一些有用的细节(我怀疑你真的需要这个代表。)。这个答案没有考虑像“{foo,bar}@ysth”这样的模式,OP没有询问
{}
,他们问了一个没有通配符的模式。但我知道我的答案怎么可能不清楚;编辑的目的是为了明确我所说的只是没有通配符的模式。
glob 'foo'