Perl while 循环不按预期运行
Perl while loop not behaving as expected
我正在使用内部睡眠的 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 循环的第二个条件。
为什么会这样???
($vm_powerState ne "poweredOn") && ($vm_toolsStatus ne "toolsOk")
FALSE && TRUE
FALSE
您应该使用 ||
而不是 &&
。
!(A && B)
等同于 (!A || !B)
编写此循环的更好方法是:
until ($vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk") {
...
}
您想循环直到
$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"
换句话说,只要其中一个有错误的值,你就想循环,但只要两个都有错误的值,你就在循环。
我正在使用内部睡眠的 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 循环的第二个条件。
为什么会这样???
($vm_powerState ne "poweredOn") && ($vm_toolsStatus ne "toolsOk")
FALSE && TRUE
FALSE
您应该使用 ||
而不是 &&
。
!(A && B)
等同于 (!A || !B)
编写此循环的更好方法是:
until ($vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk") {
...
}
您想循环直到
$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"
换句话说,只要其中一个有错误的值,你就想循环,但只要两个都有错误的值,你就在循环。