wszystko, co chciałeś wiedzieć o instrukcji if

  • 05/23/2020
  • 18 minut do przeczytania
    • j
    • x
    • t
    • d
    • s

podobnie jak wiele innych języków, PowerShell ma instrukcje warunkowo wykonywanie kodu w skryptach. Jednym z tych stwierdzeń jest stwierdzenie If., Dzisiaj przyjrzymy się jednej z najbardziej podstawowych komend w PowerShell.

Uwaga

Oryginalna wersja tego artykułu pojawiła się na blogu napisanym przez @KevinMarquette. Zespół ThePowerShell dziękuje Kevinowi za udostępnienie nam tych treści. Zapraszam na jego bloga atPowerShellExplained.com.

wykonanie warunkowe

Twoje Skrypty często muszą podejmować decyzje i wykonywać inną logikę opartą na tych decyzjach.To jest to, co mam na myśli przez warunkowe wykonanie., Masz jedną instrukcję lub wartość do oceny, a następnie wykonaj inną sekcję kodu na podstawie tej oceny. To jest dokładnie to, co robi if.

Instrukcja if

oto podstawowy przykładif Instrukcja:

$condition = $trueif ( $condition ){ Write-Output "The condition was true"}

pierwszą rzeczą, jaką robiif jest Obliczanie wyrażenia w nawiasach. Jeżeli ocenia $true, to wykonuje scriptblock w nawiasie., Jeśli wartość była $false, to przeskoczyłaby ten blok skryptów.

w poprzednim przykładzie polecenie ifoceniało zmienną $condition. Było to$true I wykonałoby polecenieWrite-Output wewnątrz bloku skryptów.

w niektórych językach można umieścić pojedynczy wiersz kodu po instrukcji if i zostanie on usunięty. W PowerShell tak nie jest. Musisz dostarczyć pełny scriptblock z aparatem ortodontycznym, aby działał poprawnie.,

operatory porównywania

najczęstszym zastosowaniem instrukcjiif jest porównanie dwóch elementów ze sobą. PowerShell ma specjalne operatory dla różnych scenariuszy porównawczych. W przypadku użycia operatora porównania wartość po lewej stronie jest porównywana z wartością po prawej stronie.

-eq dla równości

-eq sprawdza równość dwóch wartości, aby upewnić się, że są one równe sobie.,

$value = Get-MysteryValueif ( 5 -eq $value ){ # do something}

w tym przykładzie biorę znaną wartość 5I porównuję ją z moim $value, aby sprawdzić, czy pasują.

jednym z możliwych przypadków użycia jest sprawdzenie stanu wartości przed podjęciem na niej działania. Można było uruchomić usługę i sprawdzić, czy status był uruchomiony przed wywołaniem Restart-Service na nim.

w innych językach, takich jak C#, często używa się== dla równości (np.5 == $value), ale to nie działa z PowerShell., Innym częstym błędem, który ludzie popełniają jest użycie znaku równości (np:5 = $value), który jest zarezerwowany do przypisywania wartości do zmiennych. Umieszczając swoją znaną wartość na liście, czyni ten błąd bardziej niezręcznym do popełnienia.

operator ten (i inne) ma kilka odmian.,

  • -eq równość bez rozróżniania wielkości liter
  • -ieq równość bez rozróżniania wielkości liter
  • -ceq równość bez rozróżniania wielkości liter

-ne Nie równe

wiele operatorów ma operatora powiązanego, który sprawdza przeciwny wynik. -ne sprawdza, czy wartości nie są sobie równe.

if ( 5 -ne $value ){ # do something}

Użyj tego, aby upewnić się, że akcja jest wykonywana tylko wtedy, gdy jej wartość nie jest5., Dobre przypadki użycia, w których należy sprawdzić, czy usługa była w stanie działania, zanim spróbujesz ją uruchomić.

zmiany:

  • -ne wielkość liter nie jest równa
  • -ine wielkość liter nie jest równa
  • -cne wielkość liter nie jest równa
  • ul

    są to odwrotne odmiany-eq. Będę grupować te typy razem, gdy wymienię wariacje dla innych operatorów.,

    -gt-ge-lt-le dla większej lub mniejszej niż

    operatory te są używane podczas sprawdzania, czy wartość jest większa lub mniejsza od innej wartości.-gt -ge -lt -le oznacza GreaterThan, GreaterThanOrEqual, LessThan i LessThanOrEqual.,

    większa lub równa, rozróżniana wielkość liter

  • -cge większa lub równa, rozróżniana wielkość liter
  • -lt mniej niż
  • -ilt mniej niż, rozróżniana wielkość liter
  • -clt mniej niż, rozróżniana wielkość liter
  • -le mniej niż lub równe
  • -ile mniej niż lub równe, rozróżniana wielkość liter
  • -cle mniejsza lub równa, rozróżniająca wielkość liter
  • Nie wiem, dlaczego używasz opcji rozróżniających wielkość liter i niewrażliwych dla tych operatorów.,

    -podobne do wieloznacznych dopasowań

    PowerShell ma własną składnię dopasowania wzorców opartą na wieloznacznych symbolach i można go używać z operatorem-like. Te wzory wieloznaczne są dość podstawowe.

    • ? pasuje do dowolnego pojedynczego znaku
    • * pasuje do dowolnej liczby znaków
    $value = 'S-ATX-SQL01'if ( $value -like 'S-*-SQL??'){ # do something}

    ważne jest, aby zaznaczyć, że wzór pasuje do całego ciągu. Jeśli chcesz dopasować coś na środku łańcucha, musisz umieścić * na obu końcach łańcucha.,e”>

    wariacje:

    • -like wieloznaczne rozróżnianie wielkości liter
    • -ilike wieloznaczne rozróżnianie wielkości liter
    • -clike wieloznaczne rozróżnianie wielkości liter
    • -notlike bez rozróżniania wielkości liter znaki wieloznaczne nie pasują
    • -inotlike bez rozróżniania wielkości liter znaki wieloznaczne nie pasują
    • -cnotlike bez rozróżniania wielkości liter znaki wieloznaczne nie pasują

    -dopasuj Wyrażenie regularne

    Operator -match umożliwia sprawdzenie ciągu znaków pod kątem dopasowania opartego na wyrażeniach regularnych., Użyj tego, gdy wzory wieloznaczne nie są wystarczająco elastyczne dla Ciebie.

$value = 'S-ATX-SQL01'if ( $value -match 'S-\w\w\w-SQL\d\d'){ # do something}

wzorek regex domyślnie pasuje w dowolnym miejscu łańcucha. Możesz więc określić substring, który chcesz dopasować w następujący sposób:

$value = 'S-ATX-SQL01'if ( $value -match 'SQL'){ # do something}

Regex jest złożonym językiem, który sam w sobie jest wart przyjrzenia się. Mówię więcej o -match I wiele sposobów użycia regex w innym artykule.,

Variations:

  • -match case-insensitive regex
  • -imatch case-insensitive regex
  • -cmatch case-sensitive regex
  • -notmatch case-insensitive regex not matched
  • -inotmatch case-insensitive regex not matched
  • -cnotmatch case-sensitive regex not matched

-is of type

You can check a value’s type with the -is operator.,

if ( $value -is ){ # do something}

możesz tego użyć, jeśli pracujesz z klasami lub akceptujesz różne obiekty w potoku. Możesz mieć usługę lub nazwę usługi jako dane wejściowe. Następnie sprawdź, czy masz usługę i pobierz usługę, jeśli masz tylko nazwę.,

if ( $Service -isnot ){ $Service = Get-Service -Name $Service}

warianty:

  • -is typu
  • -isnot Nie typu

operatory kolekcji

gdy używasz poprzedniego operatory z pojedynczą wartością, wynikiem jest $true lub $false. Nieco inaczej to wygląda podczas pracy z kolekcją. Każda pozycja w kolekcji jest ewaluowana, a operator zwraca każdą wartość, która jest ewaluowana do $true.,

PS> 1,2,3,4 -eq 33

to nadal działa poprawnie w instrukcjiif. Tak więc wartość jest zwracana przez operatora, wtedy Instrukcja whole jest $true.

$array = 1..6if ( $array -gt 3 ){ # do something}

w szczegółach kryje się jedna mała pułapka, na którą muszę zwrócić uwagę. Używając operatora -new ten sposób łatwo jest błędnie spojrzeć na logikę wstecz. Użycie -nezkolekcją zwraca$true jeśli jakikolwiek element w kolekcji nie odpowiada twojej wartości.,

PS> 1,2,3 -ne 4123

może to wyglądać na sprytną sztuczkę, ale mamy operatory-containsI-in, które obsługują to bardziej efektywnie. I -notcontains robi to, czego oczekujesz.

-zawiera

operator-contains sprawdza kolekcję pod kątem Twojej wartości. Gdy tylko znajdzie dopasowanie, zwraca $true.

$array = 1..6if ( $array -contains 3 ){ # do something}

jest to preferowany sposób sprawdzania, czy Kolekcja zawiera twoją wartość., Korzystanie z Where-Object (lub-eq) przechodzi przez całą listę za każdym razem i jest znacznie wolniejsze.,

zmiany:

  • -contains dopasowanie rozróżniające wielkość liter
  • -icontains dopasowanie rozróżniające wielkość liter
  • -ccontains dopasowanie rozróżniające wielkość liter
  • -notcontainswielkość liter nie jest dopasowana

  • -inotcontainswielkość liter nie jest dopasowana
  • -cnotcontainswielkość liter nie jest dopasowana

-w

jest taki sam jak operator-containsz tym, że kolekcja znajduje się po prawej stronie.,

$array = 1..6if ( 3 -in $array ){ # do something}

Variations:

  • -in case-insensitive match
  • -iin case-insensitive match
  • -cin case-sensitive match
  • -notin case-insensitive not matched
  • -inotin case-insensitive not matched
  • -cnotin case-sensitive not matched

Logical operators

Logical operators are used to invert or combine other expressions.,

-nie

-not operator odwraca wyrażenie z $false do $true lub z $true do $false. Poniżej znajduje się przykład, w którym chcemy wykonać akcję, gdy Test-Path jest $false.

if ( -not ( Test-Path -Path $path ) )

większość operatorów, o których rozmawialiśmy, ma odmianę, w której nie trzeba używać operatora-not. Ale są jeszcze czasy, że jest to przydatne.

!, operator

możesz użyć ! jako aliasu dla -not.

if ( -not $value ){}if ( !$value ){}

Możesz zobaczyć! używany bardziej przez ludzi, którzy pochodzą z innych języków, takich jak C#. Wolę to wpisać, ponieważ trudno mi to zobaczyć, gdy szybko przeglądam moje Skrypty.

-i

można łączyć wyrażenia za pomocą operatora-and. Gdy to zrobisz, obie strony muszą być$true, aby całe wyrażenie było $true.,

if ( ($age -gt 13) -and ($age -lt 55) )

w tym przykładzie$age musi mieć 13 lub więcej dla lewej strony i mniej niż 55 dla prawej strony. Dodałem dodatkowe nawiasy, aby było jaśniej w tym przykładzie, ale są opcjonalne, o ile ekspresja jest prosta. Oto ten sam przykład bez nich.

if ( $age -gt 13 -and $age -lt 55 )

ocena odbywa się od lewej do prawej. Jeśli pierwsza pozycja zostanie oceniona na $false, zakończy się wcześniej i nie wykona właściwego porównania. Jest to przydatne, gdy musisz upewnić się, że wartość istnieje przed jej użyciem., Na przykład Test-Path wyświetla błąd, jeśli nadasz mu ścieżkę $null.

if ( $null -ne $path -and (Test-Path -Path $path) )

-lub

-or pozwala określić dwa wyrażenia i zwraca$true jeśli jedno z nich to$true.

if ( $age -le 13 -or $age -ge 55 )

podobnie jak w przypadku operatora-and, ocena odbywa się od lewej do prawej., Z tym wyjątkiem, że jeśli pierwsza część jest $true , to cała instrukcja jest $true I nie przetwarza reszty wyrażenia.

zanotuj również, jak działa składnia tych operatorów. Potrzebujesz dwóch oddzielnych wyrażeń. Widziałem, jak użytkownicy próbują zrobić coś takiego $value -eq 5 -or 6 nie zdając sobie sprawy z błędu.

-XOR exclusive lub

ten jest trochę nietypowy. -xor pozwala na ewaluację tylko jednego wyrażenia do$true., Więc jeśli oba elementy są $false lub oba elementy są $true , to całe wyrażenie jest $false. Innym sposobem na to jest wyrażenie tylko $true, gdy wyniki wyrażenia są różne.

rzadko kiedy ktoś używa tego operatora logicznego i nie mogę wymyślić dobrego przykładu, jak bym go kiedykolwiek użył.

operatory bitowe

operatory bitowe wykonują obliczenia na bitach w wartościach i wytwarzają nową wartość jako wynik., Nauczanie operatorów bitowych wykracza poza zakres tego artykułu, ale tutaj znajduje się ich lista.

  • -band binary I
  • -bor binary lub
  • -bxor Binary exclusive lub
  • -bnot Binary not
  • -shl shift left
  • -shr shift right

wyrażenia PowerShell

możemy użyć zwykłego PowerShell ' a wewnątrz instrukcji condition.,

if ( Test-Path -Path $Path )

Test-Path zwraca$true lub$false podczas wykonywania. Dotyczy to również poleceń zwracających inne wartości.

if ( Get-Process Notepad* )

ewaluuje do$truejeśli istnieje zwrócony proces i$false jeśli nic nie ma., Używanie wyrażeń potoków lub innych wyrażeń PowerShell jak to:

if ( Get-Process | Where Name -eq Notepad )

wyrażenia te można łączyć ze sobą za pomocą operatorów -and I -or, ale możesz użyć nawiasu, aby podzielić je na podwyrażenia.

if ( (Get-Process) -and (Get-Service) )

sprawdzanie $null

Bez wyniku lub$null wartość oblicza się na$false w instrukcjiif., Podczas sprawdzania $null najlepiej jest umieścić $null po lewej stronie.

if ( $null -eq $value )

wartości$null w PowerShell są bardzo niuanse. Jeśli jesteś zainteresowany nurkowaniem głębiej, mam artykuł o wszystkim, co chciałeś wiedzieć o $null.

przypisanie zmiennej

prawie zapomniałem dodać tę, dopóki nie przypomniał mi o tym Prasoon Karunan V.,

if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}

zwykle gdy przypisujesz wartość do zmiennej, wartość ta nie jest przekazywana do potoku orconsole. Gdy wykonujesz przypisanie zmiennej w wyrażeniu podrzędnym, jest ono przekazywane do thepipeline.

PS> $first = 1PS> ($second = 2)2

zobacz, jak przypisanie$first nie ma wyjścia, a przypisanie$second robi? Gdy przypisanie jest wykonywane w instrukcji if, wykonuje się tak samo jak przypisanie $second powyżej., Poniżej znajduje się przykład jak możesz go użyć:

if ( $process = Get-Process Notepad* ){ $process | Stop-Process}

Jeśli $process otrzymuje przypisaną wartość, to polecenie jest $true I $process zostaje zatrzymane.

upewnij się, że nie pomylisz tego z-eq, ponieważ nie jest to sprawdzanie równości. Jest to bardziej funkcja, której większość ludzi nie zdaje sobie sprawy, że działa w ten sposób.,

alternatywna ścieżka wykonania

polecenieif pozwala określić akcję nie tylko wtedy, gdy jest to$true, ale także wtedy, gdy jest to$false. W tym miejscu wchodzi w grę else.

else

Instrukcjaelse jest zawsze ostatnią częścią instrukcjiif gdy jest używana.

w tym przykładzie sprawdzamy $path, aby upewnić się, że jest to plik. Jeśli znajdziemy plik, przeniesiemy go. Jeśli nie, napiszemy Ostrzeżenie., Ten rodzaj logiki rozgałęzień jest bardzo powszechny.

zagnieżdżone if

if orazelse pobierają blok skryptu, dzięki czemu możemy umieścić w nim dowolne polecenie PowerShell, w tym inne polecenieif. Pozwala to na wykorzystanie znacznie bardziej skomplikowanej logiki.

w tym przykładzie najpierw testujemy szczęśliwą ścieżkę, a następnie podejmujemy na niej działania. Jeśli to się nie powiedzie, wykonujemy kolejną kontrolę i przekazujemy użytkownikowi bardziej szczegółowe informacje.

elseif

nie ograniczamy się tylko do jednego warunkowego sprawdzenia., Możemy połączyć if I else statementstogether zamiast zagnieżdżać je za pomocą elseif statement.

wykonanie odbywa się od góry do dołu. Topif jest obliczana jako pierwsza. Jeśli to $false, to przechodzi w dół do następnego elseif lub else na liście. Ta ostatnia else jest ostatnią akcją, którą należy wykonać, jeśli żadna z pozostałych nie zwróci $true.,

switch

w tym momencie Muszę wspomnieć oswitch. Zapewnia alternatywną składnię do roingmultiple porównań z wartością. Za pomocą switch można określić wyrażenie, a wynik zostanie porównany z kilkoma różnymi wartościami. Jeśli jedna z tych wartości pasuje, pasujący blok kodu jest usuwany. Spójrz na ten przykład:

$itemType = 'Role'switch ( $itemType ){ 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' }}

istnieją trzy możliwe wartości, które mogą pasować do $itemType. W tym przypadku pasuje do Role., Użyłem prostego przykładu, aby dać ci trochę ekspozycji na operatorswitch. O wszystkim, co chcielibyście wiedzieć o wypowiedziach switch, opowiadam w innym artykule.

Pipeline

pipeline jest unikalną i ważną cechą PowerShell. Każda wartość, która nie jest przypisana do zmiennej zostanie umieszczona w potoku. if zapewnia nam sposób wykorzystania potoku w sposób, który nie zawsze jest oczywisty.,

$discount = if ( $age -ge 55 ){ Get-SeniorDiscount}elseif ( $age -le 13 ){ Get-ChildDiscount}else{ 0.00}

każdy blok skryptu umieszcza wyniki poleceń lub wartość w potoku. Następnie przypisujemy wynik instrukcji if do zmiennej $discount. Ten przykład mógł równie łatwo przypisać te wartości do zmiennej $discount bezpośrednio w każdym bloku skryptów. Nie mogę powiedzieć, że używam tego często z if, ale mam przykład, w którym ostatnio tego używałem.,

tablica inline

mam funkcję o nazwie Invoke-SnowSql, która uruchamia plik wykonywalny z kilkoma dokumentami z linii poleceń. Oto klip z tej funkcji, gdzie buduję tablicę argumentów.

zmienne$Debug I$Path są parametrami funkcji, które są dostarczane przez użytkownika końcowego.Oceniam je inline wewnątrz inicjalizacji mojej tablicy. Jeśli $Debug jest prawdziwe, to wartości te trafiają do $snowSqlParam we właściwym miejscu. To samo dotyczy zmiennej $Path.,

Uprość złożone operacje

jest nieuniknione, że napotkasz sytuację, która ma zbyt wiele porównań do sprawdzenia, a twojeIf polecenie przewija się z prawej strony ekranu.

mogą być trudne do odczytania, a to sprawia, że jesteś bardziej podatny na popełnianie błędów. Jest kilka rzeczy, które możemy z tym zrobić.

kontynuacja linii

w PowerShell są operatory, które pozwalają zawinąć polecenie do następnej linii., Logicaloperatory -and I -or są dobrymi operatorami, których można użyć, jeśli chcesz podzielić wyrażenie na wiele wierszy.

jeszcze dużo się tam dzieje, ale umieszczenie każdego kawałka na własnej linii robi dużą różnicę.Generalnie używam tego, gdy dostaję więcej niż dwa porównania lub jeśli muszę przewijać w prawo, aby odczytać którąkolwiek logikę.

wstępne obliczanie wyników

możemy wyjąć to polecenie zif I sprawdzić tylko wynik.

to po prostu wydaje się dużo czystsze niż w poprzednim przykładzie., Masz również możliwość użycia różnej nazwy, która wyjaśnia, co naprawdę sprawdzasz. Jest to również i przykład samodzielnego dokumentowania kodu, który zapisuje niepotrzebne komentarze.

wiele poleceń if

możemy podzielić je na wiele poleceń i sprawdzać je pojedynczo. W tym przypadku używamy aflag lub zmiennej śledzącej do łączenia wyników.

musiałem odwrócić logikę, aby logika flagi działała poprawnie. Każda ocena jest osobnym if oświadczeniem., Zaletą tego jest to, że podczas debugowania można tellexactly co robi logika. Udało mi się dodać znacznie lepszą słowność w tym samym czasie.

oczywistym minusem jest to, że jest to o wiele więcej kodu do napisania. Kod jest bardziej złożony, aby spojrzeć na niego, ponieważ zajmuje pojedynczą linię logiki i eksploduje ją na 25 lub więcej linii.

używając funkcji

możemy również przenieść całą logikę walidacji do funkcji. Zobacz, jak czysto to wygląda w aglance.,

if ( Test-SecureDriveConfiguration -ADUser $user ){ # do something}

musisz jeszcze utworzyć funkcję, aby zrobić walidację, ale to znacznie ułatwia pracę z tym kodem. Ułatwia to testowanie tego kodu. W swoich testach możesz wywołać wywołanieTest-ADDriveConfiguration I potrzebujesz tylko dwóch testów dla tej funkcji. Jeden, w którym zwraca$true I drugi, w którym zwraca $false. Testowanie drugiej funkcji jest prostsze, ponieważ jest mała.

ciało tej funkcji może nadal być tym jednowierszowym, od którego zaczęliśmy lub logiką, której użyliśmy w ostatniej sekcji., To działa dobrze dla obu scenariuszy i pozwala łatwo zmienić, żemplementation później.

obsługa błędów

jednym z ważnych zastosowań instrukcjiif jest sprawdzenie warunków błędów przed uruchomieniem intoerrors. Dobrym przykładem jest sprawdzenie, czy folder już istnieje, zanim spróbujesz go utworzyć.

if ( -not (Test-Path -Path $folder) ){ New-Item -Type Directory -Path $folder}

Lubię powiedzieć, że jeśli spodziewasz się wystąpienia wyjątku, to tak naprawdę nie jest to wyjątek. Więc sprawdź swoje wartości i zweryfikuj swoje warunki, gdzie możesz.,

Jeśli chcesz zagłębić się nieco bardziej w rzeczywistą obsługę wyjątków, mam artykuł o wszystkim, co kiedykolwiek chciałeś wiedzieć o wyjątkach.

Ostatnie słowa

if oświadczenie jest takie proste, ale jest podstawowym elementem PowerShell. Przekonasz się, że używasz tego wiele razy w prawie każdym skrypcie, który piszesz. Mam nadzieję, że masz lepsze zrozumienie niż wcześniej.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *