![]() |
разобраться в выводе условного оператора
Приветствую!
Хочу, чтобы цикл завершился, если обе (количество не важно, если все) службы остановлены Может кто подсказать, почему такая конструкция не работает? Код:
$status = 'Stopped' Тут, наверное, надо понять, почему ($status -eq (Get-Service -Name $srv).Status) выдает False. Я не совсем понимаю... |
емнип break будет выводить из текущей итерации, на цикл он никак не влияет. а т.к. это while ($true), то цикл и продолжит выполняться.
($status -eq (Get-Service -Name $srv).Status) выдает False потому, что сравнивается строка с массивом. можно попробовать опрашивать каждый из элементов массива, только не руками, конечно проверки добавлять, а в цикле. их в пошике есть и кроме while. я бы использовал в данном случае пайп на foreach, ну или (вдруг) for с нуля до < $srv.length. можно, конечно, и while, и do until - как фантазия подскажет, но всё же условия выхода из цикла должно быть оговорено в самом цикле, а различные искусственные выбивания из оного - есть неправильно и весьма нехорошо. Скрипты и так очень часто по сути своей костыли, не нужно костыли подпирать дополнительными костылями. и еще один пункт, остановку сервиса лучше тоже запихать в цикл, а то он будет бесконечно пытаться проверить остановился ли сервис, который попытался остановиться один раз, у него не получилось и всё (да и то я не уверен, что в stop-Service можно скармливать массив, команда-то пройдет, а всем ли сервисам будет отдан приказ на остановку - вилами по воде). и последнее, но не по значению. Почему службы останавливаются скриптом, а не групповыми политиками? Это было бы и проще и эффективнее. |
$status = 'Stopped'
[array]$srv = 'Spooler', 'MSExchangeHM' Stop-Service -Name $srv while (((Get-Service -Name $srv)|Where-Object {$PSItem.Status -ne "Stopped"})){ sleep 5 } cls write-host "finish" -ForegroundColor Green По вашему коду. 1. while ($true) и выход по break, это считается плохой практикой, т.к. цикл может продолжаться вечно, если есть условие выхода из цикла, то надо его в условия и ставить. 2. ($status -eq (Get-Service -Name $srv).Status) вы[b] сравниваете строку с массивом, обычно в левой части условия используется вычисляемое значение, а в правой статическое значение, хотя это больше дело привычки. Поэтому True и не будет. |
Pavel Nagaev, Спасибо! Я хотел поставить условие в цикл, но что-то меня смутил и я решил сделать условие внутри.
Elven, Спасибо! я Решил, что раз я вызываю свойство объекта, его можно сравнить со строкой, видно ошибался... Это моя "фантазия" для одного ПК, в определенный момент времени (незапланированный), по этому и не через ГПО. Службы по факту другие и действия тоже. |
Цитата:
По-хорошему, опрос пары-тройки сервисов в цикле - ересь. Прочитайте внимательно man Get-Service, раздел параметры. |
Строку с массивом сравнивать можно. Предлагают через -not -ne, типа
Код:
if (-not ((Get-Service -Name $srv).Status -ne $status)) Код:
[array]::TrueForAll([String[]](Get-Service -Name $srv).Status, [Predicate[String]]{param($str) $str -eq $status}) |
Цитата:
Код:
(Get-Service service1, service2).Status.ForEach{$_ -eq 'stopped'} |
Цитата:
2. там требуется булев, а не массив булей. Непустой массив всегда кастуется к true. |
Sham, 1. И что? 2. Метод TrueForAll, если вы не в курсе, также выводит логический тип для всех значений, итогом чего становится результат их объединения согласно правилам булевой математики.
|
greg zakharov, если мы имеем коэрсию array->bool в if(), то она не по булевым правилам. [bool]@($false, $false) это $true
|
Sham, ещё раз (с чувством и расстановкой). Приведение непустого объекта к булеву типу даёт $true. Однако речь была именно о значениях в массиве, а не самом массиве. Иными словами [Boolean]@($false, $false) можно рассматривать как проверку на пустоту, но не эквант булевой математики. Не нужно переиначивать сказанное.
|
Время: 20:15. |
Время: 20:15.
© OSzone.net 2001-