在有条件的一段时间内测试文件存在是不是有任何陷阱?

Posted

技术标签:

【中文标题】在有条件的一段时间内测试文件存在是不是有任何陷阱?【英文标题】:Are there any pitfalls to testing for file existence in a while conditional?在有条件的一段时间内测试文件存在是否有任何陷阱? 【发布时间】:2011-05-13 11:24:43 【问题描述】:

我最近遇到了一行有趣的代码,它会等到某个特定的文件恢复正常:

sleep 1 until -e $file;

虽然从表面上看,这条线符合人们的预期,但我不禁觉得这里有些不对劲;编写以下内容似乎更自然:

while (1) 

    sleep 1;
    last if -e $file;

文件测试运算符是否仅用于ifunless?在while 条件中部署此类操作符是否有任何性能损失?

【问题讨论】:

性能???这里唯一的惩罚是 ping 文件系统,这比任何循环都要大一个数量级...... @Drakosha :您希望典型的文件 ping 需要多长时间?一秒钟的睡眠还不足以对抗延迟吗? 是的,看起来在任何普通文件系统/存储上都有足够的时间。我只是不明白你为什么要检查循环性能,这里可以忽略不计。 【参考方案1】:

在 while-true (while) 与 while-false (until) 循环中使用文件测试运算符或使用 if/unless 分离测试之间没有区别,与 Perl 中的其他任何东西也没有区别。

while 循环的唯一神奇情况是 ... while <$handle>;while (<$handle>) ... 在定义时将 $_ 设置为下一行。并且使用带有裸句柄的 while-false (until) 循环并没有真正的意义。

a until b 结构就是a while not b

要将sleep 1 until -e $file; 转换为while 循环,您可以使用以下代码:

sleep 1 while not -e $file;

这可以扩展为块形式:

while (not -e $file) sleep 1

或者作为带有内部转义的无限while

while (1) 
   last if -e $file;
   sleep 1;

所有这些形式都是等价的。

回答您的其余问题,大多数文件系统应该可以在两次检查之间休眠 1 秒,但如果进程没有紧急等待文件,您可以通过多种方式选择更大的数字。此外,如果您使用的设备文件系统速度较慢(存储在闪存中或通过慢速网络),您可能还需要尝试更大的值。

正如下面的ysth nitpicks,一般来说,当语句形式是返回的构造的最后一个元素时,它们的返回方式与块形式不同:do ...sub ...do FILE、eval ...

【讨论】:

@Eric :我更感兴趣的是比较在while 条件中使用文件测试而不是if 条件。 until/while not 等价不是这里的问题。 @Zaid => 这是同一个问题,文件测试,就像布尔上下文中的任何其他操作一样,在循环内的条件(if)与条件循环(@ 987654346@) @Zaid:从你的“看起来更自然”来看,听起来它使用 until 语句修饰符让你感到困扰。 直到略有不同:比较 print do sleep 1 until -e $file print do while (not -e $file) sleep 1 @ysth :until 的使用一点也不困扰我。将until 与文件测试一起使用即可。我还没有遇到将文件测试与循环条件结合使用的示例。【参考方案2】:

即使文件存在,您更自然的方式似乎也是在开始时休眠。

while(not -e $file)  sleep 1; 

对我来说似乎更好,这正是 sleep 1 until -e $file; 的同义词,但在我看来更容易理解。

【讨论】:

不是一个确切的同义词;一个会返回 false,一个会返回 true。

以上是关于在有条件的一段时间内测试文件存在是不是有任何陷阱?的主要内容,如果未能解决你的问题,请参考以下文章

在有条件的熊猫中除以前一行

将 Cassandra 集群部署到一组 Linode VPS 实例是不是有任何“陷阱”?

尝试在 Windows Server 2008 Web 版上运行 DNN 是不是有任何陷阱?

如何在有条件的情况下改变状态 - React

测试 glob 在 Bash 中是不是有任何匹配项

ViewStub 在有条件地膨胀多个布局时引发错误