【问题标题】:Perl while loop not behaving as expectedPerl while 循环未按预期运行
【发布时间】:2015-08-04 15:04:07
【问题描述】:

我正在使用带有睡眠的 while 循环来检查事件何时发生(我正在启动虚拟机,然后使用循环等待并确保它已打开电源并启动)。

我的循环如下:

my $vm_powerState = $vm_view->runtime->powerState->val;
my $vm_toolsStatus = $vm_view->guest->toolsStatus->val;
while (
    ($vm_powerState ne "poweredOn")
 && ($vm_toolsStatus ne "toolsOk")
) {
    debug($vmname);
    $vm_view = Vim::find_entity_view(
        view_type => 'VirtualMachine',
        filter => {"config.name" => $vmname }
    );
    debug ($vm_powerState . "\nbla\n" . $vm_toolsStatus);
    # $vm_toolsStatus = $vm_view->guest->toolsStatus->val
    if (my $ref = eval { $vm_view->can("guest")} )
    {
        print "OK\n";
        print $vm_view->guest->toolsStatus->val;
        $vm_toolsStatus = $vm_view->guest->toolsStatus->val;
    }
    $vm_powerState = $vm_view->runtime->powerState->val if (defined($vm_view));
    debug($vm_powerState . "\n\nbla222\n\n" . $vm_toolsStatus);
    debug("...");
    sleep(1);
}
debug ($vm_toolsStatus);
debug ("VM is ON");

简而言之,我获得了 VM 的状态(默认为 poweredOff 和 toolsNotRunning),然后循环直到它们都具有良好的值(poweredOn 和 toolsOk)。应该可以吧?

嗯,不。 powerState 更改为 poweredOn 后的第一个循环,循环结束,即使 toolsStatus 为“toolsNotRunning”。

这是我输出的主要部分:

$VAR1 = \'VM TESTVM2is being turned on';
$VAR1 = \'Waiting for the VM to turn on and boot, it might take some time';
$VAR1 = \'TESTVM2';
$VAR1 = \'poweredOff
bla
toolsNotRunning';
OK
toolsNotRunning$VAR1 = \'poweredOn

bla222

toolsNotRunning';
$VAR1 = \'...';
$VAR1 = \'toolsNotRunning';
$VAR1 = \'VM is ON';

如你所见,powerState 的值为 powerOn 后程序立即退出,即使 while 循环的第二个条件显然不满足。

为什么会这样???

【问题讨论】:

    标签: perl while-loop vmware-tools


    【解决方案1】:
    ($vm_powerState ne "poweredOn") && ($vm_toolsStatus ne "toolsOk")
    FALSE && TRUE
    FALSE
    

    您应该使用|| 而不是&&

    !(A && B) 等价于(!A || !B)

    编写此循环的更好方法是:

    until ($vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk") {
      ...
    }
    

    【讨论】:

    • 哇,好吧,我不知道这是如何解释条件的。谢谢
    • @AdrianTodorov,while 条件没有什么特别之处。这是基本的布尔代数。
    • @ThisSuitIsBlackNot,这是个好主意。我一直忘记 Perl 有一个普通的 until 循环。
    • @Adrian Todorov,关于“我的解释是'直到两个条件都为假'”,但您写道“两个条件都为真”
    • @Adrian Todorov,关于“这是 Perl 特定的吗?”,否。&& 在 Perl 和 C(以及 Java 和 JS 以及 SQL 和 ...)中实现“逻辑与”跨度>
    【解决方案2】:

    你想循环直到

    $vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk"
    

    这意味着你要在while循环

    !( $vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk" )
    

    等效:

    !( $vm_powerState eq "poweredOn" ) || !( $vm_toolsStatus eq "toolsOk" )
    

    等效:

    $vm_powerState ne "poweredOn" || $vm_toolsStatus ne "toolsOk"
    

    换句话说,只要其中一个有错误的值,你就想循环,但只要两个都有错误的值,你就在循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-01
      • 2015-10-10
      • 1970-01-01
      • 2018-04-24
      • 2013-05-13
      • 2015-03-31
      • 2021-04-04
      • 2012-04-05
      相关资源
      最近更新 更多