A trap tárgyalásának elején már láthattuk, hogy azzal hibakezelést csak megszakító hibákra tudunk készíteni, legfeljebb a trap végére tett continue kulcsszóval átalakítjuk a hibát nem megszakítóra. De vajon hogyan tudunk nem megszakító hibákat kezelni? Erre nincs külön kulcsszó, a többi PowerShelles nyelvi eszközzel kell ezt megoldani.
Az egyik ilyen helyzet, hogy a nem megszakító hibát nem akarom csak azért megszakítóvá alakítani, hogy aztán egy continue-val elnyomhassam a hibajelzést, hanem eleve nem akarok látni semmilyen hibainformációt a konzolon. Ehhez azt kell tudni, hogy külön outputja van a hibajelzéseknek, így lehet olyat is csinálni, hogy csak ezeket a hibajelzéseket küldjük át egy fájlba, vagy akár a semmibe. Nézzünk erre példát:
[43] PS C:\> Remove-Item nemlétezőfájl.txt 2> $null
Ez tehát a „2> ” operátor, ami a 2-es számú outputot, a hibajelzések outputját irányítja a semmibe. (Amúgy „1>” nem létezik, csak a kettessel kezdődő változat.)
Ha pont ellentétes lenne a feladat, azaz valami egyedi, saját hibajelzést szeretnénk adni a „gyári” jelzés helyett, arra külön write-... kezdetű cmdletek állnak rendelkezésünkre. Ezekkel szintén nem a „normál” outputra, hanem erre a hibajelzések számára elkülönített outputra küldhetjük a jelzést.
[67] PS C:\powershell2\scripts> filter bulk-remove
>> {
>> if (-not (Test-Path $_))
>> { Write-Warning "Nincs ilyen file: $_!" }
>> else
>> { Remove-Item $_ }
>> }
>>
A fenti filter kifejezéssel definiálok egy olyan fájltörlő függvényt, amely először ellenőrzi, hagy van-e ott ténylegesen fájl, amit megadott a felhasználó, és ha nincs, akkor nem csúnya hibajelzést ad, hanem csak egy sárga színű figyelmeztetést a write-warning cmdlet segítségével.
[68] PS C:\powershell2\scripts> "nincs.txt", "file.txt" | bulk-remove
WARNING: Nincs ilyen file: nincs.txt!
Ez azért is jó, mert ez nem kerül be a $error tömbbe, így nem „terheli” azt. Természetesen lehetne piros feliratú write-error -t is használni, ekkor olyan hibajelzést kapunk, ami bekerül az $error tömbbe.
Nem csak ilyen következményei vannak a write-error és write-warning használatának. Ha átállítjuk a következő automatikus változókat, akkor szabályozhatjuk függvényünk, szkriptünk futását is:
[79] PS C:\powershell2\scripts> $WarningPreference
Continue
[80] PS C:\powershell2\scripts> $ErrorActionPreference
Continue
Természetesen a write-error még profibbá tehető az Exception objektum ok használatával:
filter bulk-remove
{
if (-not (Test-Path
$_))
{ Write-Error
-Exception `
(New-Object
System.IO.FileNotFoundException `
-arg
"Nincs ilyen file!",$_) }
else
{
Remove-Item
$_
}
}
És ennek kimenete hiba esetén:
[2] PS C:\> "semmi.txt" | bulk-remove
bulk-remove
: Nincs ilyen file!
At line:1
char:26
+
"semmi.txt" | bulk-remove <<<<
+ CategoryInfo : NotSpecified: (:) [Write-Error],
FileNotFoundEx
ception
+ FullyQualifiedErrorId :
System.IO.FileNotFoundException,bulk-remove
[3] PS C:\> $error[0].exception.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileNotFoundException System.IO.IOExce...
A [83]-as sorban láthatjuk, hogy ez a hiba már „igazi” FileNotFoundException lett.
A másik lehetőség a $? automatikus változó vizsgálatával történő hibakezelés. Ez a változó az előző kifejezés végrehajtásának eredményét tartalmazza.
filter bulk-remove
{
remove-item
$_ -ErrorAction silentlycontinue
if (!$?)
{ $Error[0].categoryinfo.reason}
}
A fenti, módosított filterben maga a remove-item hibajelzése el van nyomva (silentlycontinue), ennek ellenére azért a hibakód belekerül az $error változóba, illetve a hiba ténye miatt $false lesz a $? változó, így reagálhatunk rá. Az if szerkezet szkriptblokkjára akkor adódik rá a vezérlés, ha hibát adott az aktuális elem eltávolítása.