Perl while循环未按预期运行

Perl while循环未按预期运行,perl,while-loop,vmware-tools,Perl,While Loop,Vmware Tools,我正在使用一个内部带有睡眠的while循环来检查事件何时发生(我正在启动一个虚拟机,然后使用该循环等待并确保它已通电并启动) 我的循环如下: my $vm_powerState = $vm_view->runtime->powerState->val; my $vm_toolsStatus = $vm_view->guest->toolsStatus->val; while ( ($vm_powerState ne "poweredOn") &

我正在使用一个内部带有睡眠的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和toolsnoturning),然后循环,直到它们都具有良好的值(poweredOn和toolsOk)。应该有用吧

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

以下是我输出的主要部分:

$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';
正如您所看到的,即使while循环的第二个条件明显不满足,程序也会在powerState的值为poweredOn之后立即退出

为什么会这样

($vm_powerState ne "poweredOn") && ($vm_toolsStatus ne "toolsOk")
FALSE && TRUE
FALSE
您应该使用
|
而不是
&&

!(A和&B)
相当于
(!A|||!B)

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

until ($vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk") {
  ...
}
您应该使用
|
而不是
&&

!(A和&B)
相当于
(!A|||!B)

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

until ($vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk") {
  ...
}
你想循环直到

$vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk"
这意味着你想在

!( $vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk" )
等价物:

!( $vm_powerState eq "poweredOn" ) || !( $vm_toolsStatus eq "toolsOk" )
$vm_powerState ne "poweredOn" || $vm_toolsStatus ne "toolsOk"
等价物:

!( $vm_powerState eq "poweredOn" ) || !( $vm_toolsStatus eq "toolsOk" )
$vm_powerState ne "poweredOn" || $vm_toolsStatus ne "toolsOk"
换句话说,只要其中一个有错误的值,您就想循环,但只要两个都有错误的值,您就是在循环。

您想循环到

$vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk"
这意味着你想在

!( $vm_powerState eq "poweredOn" && $vm_toolsStatus eq "toolsOk" )
等价物:

!( $vm_powerState eq "poweredOn" ) || !( $vm_toolsStatus eq "toolsOk" )
$vm_powerState ne "poweredOn" || $vm_toolsStatus ne "toolsOk"
等价物:

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

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

哇,好吧,我不知道这是如何解释条件的。Thanks@AdrianTodorov,while条件没有什么特别的。这是基本布尔代数。@ThisSuitesBlack不是,这是个好主意。我总是忘记Perl有一个简单的
,直到
循环。@Adrian Todorov,Re“我的解释是‘直到两个条件都为假’”,但是你写了“当两个条件都为真时”@Adrian Todorov,Re“这是Perl特有的吗?”,不。
&
在Perl和C(以及Java、JS和SQL等)中实现了“逻辑and”,我不知道这是如何解释条件的。Thanks@AdrianTodorov,while条件没有什么特别的。这是基本布尔代数。@ThisSuitesBlack不是,这是个好主意。我总是忘记Perl有一个简单的
,直到
循环。@Adrian Todorov,Re“我的解释是‘直到两个条件都为假’”,但是你写了“当两个条件都为真时”@Adrian Todorov,Re“这是Perl特有的吗?”,不。
&
在Perl和C(以及Java和JS,SQL和…)中实现了“逻辑and”