リダイレクトとは、処理を行った結果の出力先を別の場所へ変更することを意味します。
通常PowerShell上で、あるコマンドを実行してエラーが発生した場合は、コンソールウィンドウにエラーメッセージが表示されます。ここでは、このエラーをファイルに出力することを「リダイレクトする」と呼んでいます。
PowerShellでエラーをファイルにリダイレクトするには、リダイレクト演算子を使用した3つの方法があります。
この演算子は、エラーの内容をファイルに出力します。出力先のファイルが既に存在する場合には上書きをします。
下記は、dirコマンドで存在しないファイルを指定した場合の例です。(「C:\Work」フォルダに「HOGE.txt」が存在しないものとします)
PS C:\Work> dir HOGE.txt Get-ChildItem : パス 'C:\Work\HOGE.txt' が存在しないため検出できません。 発生場所 行:1 文字:4 + dir <<<< HOGE.txtでは、このエラーをファイルにリダイレクトしてみます。
PS C:\Work> dir HOGE.txt 2>err.txt上記のように、2>演算子の後ろに、エラーメッセージを書き込むファイル名を記述します。
では、Get-Contentコマンドレットを使用して作成された「err.txt」ファイルの中身をみてみましょう。
PS C:\Work> Get-Content err.txt Get-ChildItem : パス 'C:\Work\HOGE.txt' が存在しないため検出できませ ん。 発生場所 行:1 文字:4 + dir <<<< HOGE.txt 2>err.txtエラーの内容がリダイレクトされていることが分かります。
この演算子は、エラーの出力先のファイルが既に存在する場合は、追記書き込みを行います。
追記されることを確認するために、出力先のファイルは先ほどと同じ「err.txt」とします。また。異なるエラーメッセージが記述されるようmkdirコマンドに変更しました。
PS C:\Work> mkdir HO*GE 2>> err.txt実行したら、先ほど同様Get-Contentコマンドレットで確認してみましょう。
PS C:\Work> Get-Content err.txt Get-ChildItem : パス 'C:\Work\HOGE.txt' が存在しないため検出できませ ん。 発生場所 行:1 文字:4 + dir <<<< HOGE.txt 2>err.txt New-Item : パスに無効な文字が含まれています。 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $pathsエラーメッセージが追記されていることが分かります。
この演算子を使用すると、エラーの内容を変数に書き込むことができます。
$err = mkdir HO*GE 2>&1では、エラーの内容が変数に代入されているかを確認してみましょう。
caption PS C:\Work> $err New-Item : パスに無効な文字が含まれています。 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $paths通常、変数の内容を確認してもメッセージに色がつかないのですが、2>&1演算子を使用して代入された値は、赤色で表示されていることが分かります。
これは、変数に代入された値はエラーであることを示すErrorRecordオブジェクトとなるからです。(Errorオブジェクトは後述します))
PS C:\Work> $err.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ErrorRecord System.Object -ErrorVariableパラメータ 2>&1 演算子を使用する以外に -ErrorVariableパラメータを使用しても変数にエラーを代入することが可能です。 PS C:\Work> Get-ChildItem HOGE.txt -ErrorVariable err1 Get-ChildItem : パス 'C:\Work\HOGE.txt' が存在しないため検出できませ ん。 発生場所 行:1 文字:14 + Get-ChildItem <<<< HOGE.txt -ErrorVariable err1 -ErrorVariableパラメータの後ろには、エラー内容を代入するための変数を指定します。このとき、指定する変数に $を付加してはいけないことに注意してください。 $Error変数は、PowerShellの操作時に発生したすべてのエラーが格納されますが、この -ErrorVariableパラメータを使用した場合は、そのとき発生したエラーの内容だけを特定の変数に代入できるという違いがあります。さきほど、2>&1演算子で代入したエラーはErrorRecordオブジェクトとなることを説明しました。では、ErrorRecordオブジェクトにはどのようなメンバーが備わっているかを確認したいと思います。
先ほどの変数$errに対してGet-Memberコマンドレットを使用し、どのようなメンバーがあるかを確認してみたいと思います。
PS C:\Work> $err | Get-Member TypeName: System.Management.Automation.ErrorRecord Name MemberType Definition ---- ---------- ---------- Equals Method System.Boolean Equals(Object obj) GetHashCode Method System.Int32 GetHashCode() GetObjectData Method System.Void GetObjectData(SerializationInfo info, StreamingContext context) GetType Method System.Type GetType() get_CategoryInfo Method System.Management.Automation.ErrorCategoryInfo get_CategoryInfo() get_ErrorDetails Method System.Management.Automation.ErrorDetails get_ErrorDetails() get_Exception Method System.Exception get_Exception() get_FullyQualifiedErrorId Method System.String get_FullyQualifiedErrorId() get_InvocationInfo Method System.Management.Automation.InvocationInfo get_InvocationInfo() get_TargetObject Method System.Object get_TargetObject() set_ErrorDetails Method System.Void set_ErrorDetails(ErrorDetails value) ToString Method System.String ToString() writeErrorStream NoteProperty System.Boolean writeErrorStream=True CategoryInfo Property System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;} ErrorDetails Property System.Management.Automation.ErrorDetails ErrorDetails {get;set;} Exception Property System.Exception Exception {get;} FullyQualifiedErrorId Property System.String FullyQualifiedErrorId {get;} InvocationInfo Property System.Management.Automation.InvocationInfo InvocationInfo {get;} TargetObject Property System.Object TargetObject {get;}多くのメンバーを備えていることが確認できます。これらの中から、主要なものについて説明したいと思います。
このプロパティは文字通り、エラーの種類についての情報が格納されています。
PS C:\Work> $err.CategoryInfo Category : InvalidArgument Activity : New-Item Reason : ArgumentException TargetName : C:\Work\HO*GE TargetType : StringCategoryが「InvalidArgument」となっていることが分かります。これはdirコマンドに対して、無効な文字が含まれたパスを指定しているためです。さらにReason(発生理由)をみると、「ArgumentException」という例外が発生したことが分かります。
Exceptionプロパティ自体もさまざまなメンバーを持っていますが、規定のプロパティはMessageとなっており、エラーの内容を確認することができます。
PS C:\Work> $err.Exception パスに無効な文字が含まれています。このプロパティはエラーの発生場所に関する情報が格納されます。PositionMessageの欄を見ると、「1行目の34文字目でエラーが発生した」ということを確認できます。
PS C:\Work> $err.InvocationInfo MyCommand : New-Item ScriptLineNumber : 1 OffsetInLine : -2147483648 ScriptName : Line : param([string[]]$paths); New-Item -type directory -path $paths PositionMessage : 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $paths InvocationName : New-Item PipelineLength : 1 PipelinePosition : 1このプロパティには、エラー発生時の操作対象オブジェクトが格納されます。ただし、すべてのエラーがこのプロパティを設定するわけではないため、Nullの場合もあります。
PS C:\Work> $err.TargetObject C:\Work\HO*GEこのようにErrorRecordオブジェクトには、エラーの原因を解明する上で役立つ情報が格納されています。
PowerShellではエラーが発生するごとに、そのエラー内容を保存している変数があります。この変数は$Errorという自動変数で、配列型となっています。
また、この変数に格納できる最大要素数は自動変数$MaximumErrorCountで決められており、256のエラー(規定値)を保持します。
では、実際にエラーを発生させて$Error変数がどのように変わっていくのかを見てみます。(PowerShellを立ち上げていた方は、念のため起動し直してから始めてください)
まずは、PowerShell立ち上げ時点の$Error変数の内容を確認しておきましょう。
PS C:\Work> $Error PS C:\Work>この時点でエラーは発生していないので、何も格納されていません。下記のように入力して、エラーを発生させます。
PS C:\Work> dir HOGE Get-ChildItem : パス 'C:\Work\HOGE' が存在しないため検出できません。 発生場所 行:1 文字:4 + dir <<<< HOGEエラーを発生させた後の$Error変数を確認してみます。
PS C:\Work> $Error Get-ChildItem : パス 'C:\Work\HOGE' が存在しないため検出できません。 発生場所 行:1 文字:4 + dir <<<< HOGE上記のように、先ほど発生した内容が格納されていることが分かります。
$Errorは配列なので、要素数の変化について確認してみます。要素数はCountプロパティで確認することができます。
PS C:\Work> $Error.Count 1エラーは1つしか発生していないので、要素数は"1"となります。
次に、もう1つエラーを発生させてみましょう。
PS C:\Work> mkdir HO*GE2 New-Item : パスに無効な文字が含まれています。 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $pathsこの状態で$Error変数の内容を確認してみると
PS C:\Work> $Error New-Item : パスに無効な文字が含まれています。 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $paths Get-ChildItem : パス 'C:\Work\HOGE' が存在しないため検出できません。 発生場所 行:1 文字:4 + dir <<<< HOGE少し見づらいですが、2つのエラーが格納されていることが分かります。
$Error変数は配列なので、下記のように要素番号を指定して1つずつエラーを取り出すことができます。
PS C:\Work> $Error[0] New-Item : パスに無効な文字が含まれています。 発生場所 行:1 文字:34 + param([string[]]$paths); New-Item <<<< -type directory -path $pathsまた$Error変数は、新しいエラーが発生すると常に$error[0]へ書き込みます。以前に$error[0]に代入されていたエラーは$error[1]へ、$error[1]のエラーは$error[2]へと移動します。
このことから、最新のエラーは$error[0]を参照すればよいことが分かります。
この変数は、最後に実行したコマンドの実行状態を保持するブール変数です。直前の処理が成功した場合にはTrue、それ以外の場合はFalseとなります。
まずは、この変数の動きを見てみましょう。何もエラーが発生していない状態で、$?変数の中身を確認すると
PS C:\Work> $? True上記のようにTrueを返します。
下記のようにエラー発生させ
PS C:\Work> Get-ChildItem HOGE Get-ChildItem : パス 'C:\Work\HOGE' が存在しないため検出できません。 発生場所 行:1 文字:14 + Get-ChildItem <<<< HOGE$?の値を確認すると
PS C:\Work> $? False上記のようにFalseを返します。
この$?変数は特にスクリプトの中で効果を発揮します。
下記はカレントディレクトリに「HOGE」が存在するかを確認していますが、存在しない場合にはエラーが発生します。しかし、2>&1演算子を利用してエラー内容を$err変数に書き込むので、エラーメッセージは表示されません。また、エラーが発生しても処理は続行します。
このような場合に$?を使用することで、直前のコマンドが成功したか否かを確認することが可能となります。
$err = Get-ChildItem HOGE 2>&1 if ($?) {"エラーは発生しませんでした" } else {"エラーが発生しました"}PowerShellでは、エラーの表示方法を制御することが可能で
コマンドレット使用時に発生したエラーすべてのエラーそれぞれに対して行うことができます。
コマンドレット使用時のエラー表示を制御するには-ErrorActionパラメータを、すべてのエラー表示の制御を行うには$ErrorActionPreference変数を設定します。
設定可能な値は共通です。それぞれについて見ていきます。
デフォルトではcontinueになっています。エラーが発生した場合はメッセージが出力されます。
エラーの内容は$Error変数に追加され、$?変数はFalseとなります。スクリプトは次の行から実行されます。
エラーが発生してもメッセージは出力されません。
エラーの内容は$Error変数に追加され、$?変数はFalseとなります。スクリプトは次の行から実行されます。
エラーが発生した時点で処理を中止します。
エラーの内容は$Error変数に追加され、$?変数はFalseとなります。スクリプトは停止します。
このパラメータは、コマンドレット使用時に発生したエラーの表示を制御します。
-ErrorActionパラメータにcontinueを設定した場合は、エラーメッセージが出力されます。
PS C:\Work> Get-ChildItem Hoge -ErrorAction "continue" Get-ChildItem : パス 'C:\Work\Hoge' が存在しないため検出できません。 発生場所 行:1 文字:14 + Get-ChildItem <<<< Hoge -ErrorAction "continue"-ErrorActionパラメータにsilentlycontinueを設定した場合は、エラーメッセージが出力されません。
PS C:\Work> Get-ChildItem Hoge -ErrorAction "silentlycontinue" PS C:\Work>-ErrorActionパラメータにstopを設定した場合は、エラーアクション設定によって実行が中止されたことを示すメッセージが表示され、処理を中止します。
PS C:\Work> Get-ChildItem Hoge -ErrorAction "stop" Get-ChildItem : シェル変数 "ErrorActionPreference" が Stop に設定さ れているため、コマンドの実行が停止しました。 パス 'C:\Work\Hoge' が存在しないため検出できません。 発生場所 行:1 文字:14 + Get-ChildItem <<<< Hoge -ErrorAction "stop"この変数に設定した値は、発生したエラーすべてのエラー表示を制御します。
$ErrorActionPreference変数への値の設定は、=演算子の左辺に$ErrorActionPreference変数を、右側に設定する値を記述します。
試しに$ErrorActionPreference変数へsilentlycontinueを設定してみます。
PS C:\Work> $ErrorActionPreference = "silentlycontinue"この状態で、エラーが発生するコマンドを実行してみます。
PS C:\Work> Get-ChildItem Hoge PS C:\Work>エラーメッセージは表示されません。
$ErrorActionPreference変数にsilentlycontinueを設定した効果が現れていることが分かります。(元に戻すには$ErrorActionPreference="Continue"と入力してください。)
PowerShellではtrap文を用いることで、例外処理を行うことができます。trap文の構文は下記の通りです。
trap [<例外の種類>] { trap文本体 }「例外の種類」は省略することが可能です。
例えば下記では、1/$Nullを実行されるゼロ除算例外が発生するため、trapへ制御が移り「例外発生」の文字列を表示します。
PS C:\Work> trap >> {"例外発生" } >> 1/$Null >> 例外発生 0 で除算しようとしました。 発生場所 行:3 文字:3 + 1/$ <<<< Null次に、例外が発生したら処理を中断する方法について見てみましょう。中断するにはbreakを使用します。
trap2.ps1 trap { "例外が発生しました" break } 1/$Null Write-Host "スクリプト終了"このスクリプトは、例外が発生するとtrapを実行するので「例外が発生しました」のメッセージを表示します。さらにbreakが実行されエラーメッセージを表示し、処理を中断します。
この結果、「スクリプト終了」の文字列は表示されません。
PS C:\Work> ./trap2.ps1 例外が発生しました 0 で除算しようとしました。 発生場所 C:\Work\trap.ps1:7 文字:3 + 1/$ <<<< Null次にtrapの中でcontinueを使用するとどうなるか、見てみましょう。
trap3.ps1 trap { "例外が発生しました" continue } 1/$Null Write-Host "スクリプト終了"実行結果は下記のとおりで、例外が発生すると「例外が発生しました」のメッセージが表示され、最後の「スクリプト終了」が表示されます。
PS C:\Work> ./trap3.ps1 例外が発生しました スクリプト終了このようにcontinueを使用した場合はエラーメッセージは表示されず、trapを実行後、例外が発生した次の行から処理が再開されます。
今回は
エラーのリダイレクト-ErrorRecordオブジェクト$Error変数$?変数-ErrorActionパラメータと$ErrorActionPreference変数--ErrorVariableパラメータ例外処理について取り上げました。
PowerShellでは、エラーに対するさまざまな対処方法および内容の取得方法が準備されています。このことを理解し、スクリプト開発に役立てていただければと思います。
转载于:https://www.cnblogs.com/c-x-a/p/4488144.html