Windows PowerShell 入門(10)-デバッグ編
対象読者
- Windows PowerShellでコマンドレット操作ができる方
- 何らかのプログラミング経験があればなお良い
必要環境
- Windows PowerShell
デバッグメッセージの出力
PowerShellではデバッグ用のメッセージを表示しながら開発が行えるように、Write-Debugという専用のコマンドレットを備えています。
コンソールにメッセージを表示するコマンドレットとしてはWrite-Hostコマンドレットがありますが、両者には次のような違いがあります。
- Write-Hostコマンドレットは、実行すれば必ず表示を行う。
- Write-Debugコマンドレットは、
$DebugPreferenceシェル変数によって表示制御が行われる
$DebugPreferenceシェル変数はデバッグ時の振る舞いを変更する特殊な変数であり、下記の4つの値を指定することが可能です。
| 値 | 説明 |
| "Continue" | Write-Debugに指定されたメッセージを出力 |
| "SilentlyContinue" | Write-Debugに指定されたメッセージを出力しない |
| "Stop" | Write-Debugに指定されたメッセージを出力した後、動作を停止 |
| "Inquire" | Write-Debugに指定されたメッセージを出力後、続行するかを確認 |
下記スクリプトを準備して(ここでは「C:\Work\Debug.ps1」として保存)、$DebugPreferenceシェル変数のそれぞれの値の挙動を確認してみたいと思います。
$a = 2
$b = 3
$c = $a + $b
Write-Debug "Line4: $c"
$a = 4
$b = 5
$c = $a + $b
Write-Debug "Line8: $c"
Debug.ps1の各行の意味は下記の通りです。
- 1行目:$aに2を代入
- 2行目:$bに3を代入
- 3行目:$aと$bの和を$cに代入
- 4行目:Write-Debugコマンドレットによる文字列の出力。ここでは「Line4:」と変数$cに代入された値が連結した文字列を出力。
- 5行目:$aに4を代入
- 6行目:$bに5を代入
- 7行目:$aと$bの和を$cに代入
- 8行目:Write-Debugコマンドレットによる文字列の出力。ここでは「Line8:」と変数$cに代入された値が連結した文字列を出力。
Continue
$DebugPreferenceに値Continueを設定した場合の動作を見てみましょう。
まずは、下記のようにして $DebugPreferenceの設定を変更します。
PS C:\Work> $DebugPreference = "Continue"
次に、作成したスクリプトを実行してみましょう。
PS C:\Work> ./Debug.ps1
デバッグ: Line4: 5
デバッグ: Line8: 9
Write-Debugコマンドレットに指定したメッセージを出力することがわかります。
SilentlyContinue
$DebugPreferenceに値SilentlyContinueを設定した場合の動作を見てみましょう。
まずは、下記のようにして $DebugPreferenceシェル変数の設定を変更します。
PS C:\Work> $DebugPreference = "SilentlyContinue"
スクリプトを実行します。
PS C:\Work> ./Debug.ps1
PS C:\Work>
スクリプト中の4行目と8行目にあるWrite-Debugに指定したメッセージは出力されずに終了することがわかります。
Stop
$DebugPreferenceに値Stopを設定した場合の動作を見てみましょう。
まずは、下記のようにして $DebugPreferenceシェル変数の設定を変更します。
PS C:\Work> $DebugPreference = "Stop"
スクリプトを実行します。
PS C:\Work> ./Debug.ps1
デバッグ: Line4: 5
Write-Debug : シェル変数 "DebugPreference" が Stop に設定されているため、コマンドの実行が停止されました
発生場所 C:\Work\Debug.ps1:4 文字:12
+ Write-Debug <<<< "Line4: $c"
1つめのWrite-Debugで指定されたメッセージを表示した後、エラーメッセージを表示して処理を中断することが分かります。
Inquire
$DebugPreferenceに値Inquireを設定した場合の動作を見てみましょう。
まずは、下記のようにして $DebugPreferenceシェル変数の設定を変更します。
PS C:\Work> $DebugPreference = "Inquire"
スクリプトを実行します。
PS C:\Work> ./Debug.ps1
デバッグ: Line4: 5
確認
この操作を続行しますか?
[Y] はい(Y) [A] すべて続行(A) [H] コマンドの中止(H) [S] 中断(S) [?] ヘルプ (既定値は "Y"):
1つめのWrite-Debugで指定されたメッセージを表示した後に、スクリプトを実行するかを確認してくることがわかります。
ここで[Y]または[A]を押すと、スクリプトが続行されます。
確認
この操作を続行しますか?
[Y] はい(Y) [A] すべて続行(A) [H] コマンドの中止(H) [S] 中断(S) [?] ヘルプ (既定値は "Y"):
デバッグ: Line8: 9 確認
この操作を続行しますか?
[Y] はい(Y) [A] すべて続行(A) [H] コマンドの中止(H) [S] 中断(S) [?] ヘルプ (既定値は "Y"):
このように、Write-Debugコマンドレットと$DebugPreference変数を使用することで、デバッグメッセージの出力の振る舞いを制御することが可能です。
Set-PSDebugコマンドレットによるデバッグ
PowerShellには、スクリプトのデバッグを行うために、Set-PSDebugというコマンドレットがあります。書式は大きく2つに分けることができます。
下記は、スクリプトのデバッグ機能の切り替え、トレース レベルの設定、および strict モードの切り替えを行います。
Set-PSDebug [-Trace 数値] [-Step] [-Strict]
一方、こちらはすべてのスクリプトデバッグ機能を無効にします。
Set-PSDebug -Off
-Traceパラメータ
-Traceパラメータに指定できる値には下記の3つがあります。
| 値 | 説明 |
| 0 | スクリプトのトレースを無効にする |
| 1 | 実行されるスクリプト行をトレースする |
| 2 | スクリプト行、変数の代入、関数呼び出し、およびスクリプトをトレースする |
では、さきほどのスクリプトファイル(Debug.ps1)を使用して実験してみましょう。
-Traceに0を指定した場合
まずはSet-PSDebugコマンドレットによるスクリプトファイルのデバッグ方法ですが
PS C:\Work> Set-PSDebug -trace 0; ./Debug.ps1
のようにします。
-Traceパラメータに0を指定した場合の実行結果は下記の通りで、値0はトレースが無効となっているために1行だけ表示して終わっています。
デバッグ出力の行には、先頭に「デバッグ:」と表示されることに注意してください。
PS C:\Work> Set-PSDebug -trace 0; ./Debug.ps1
デバッグ: 1+ Set-PSDebug -trace 0; ./Debug.ps1
-Traceに1を指定した場合は行トレースとなりますので、すべての行がデバッグ表示されます。
-Traceに1を指定した場合
PS C:\Work> Set-PSDebug -trace 1; ./Debug.ps1
デバッグ: 1+ Set-PSDebug -trace 1; ./Debug.ps1
デバッグ: 1+ $a = 2
デバッグ: 2+ $b = 3
デバッグ: 3+ $c = $a + $b
デバッグ: 4+ Write-Debug "Line4: $c"
デバッグ: 5+ $a = 4
デバッグ: 6+ $b = 5
デバッグ: 7+ $c = $a + $b
デバッグ: 8+ Write-Debug "Line8: $c"
-Traceに2を指定した場合
-Traceに2を指定した場合は変数の代入、関数呼び出しなど、各行で行われている詳細情報を見ることができます。
PS C:\Work> Set-PSDebug -trace 2; ./Debug.ps1
デバッグ: 1+ Set-PSDebug -trace 2; ./Debug.ps1
デバッグ: ! CALL script 'Debug.ps1'
デバッグ: 1+ $a = 2
デバッグ: ! SET $a = '2'.
デバッグ: 2+ $b = 3
デバッグ: ! SET $b = '3'.
デバッグ: 3+ $c = $a + $b
デバッグ: ! SET $c = '5'.
デバッグ: 4+ Write-Debug "Line4: $c"
デバッグ: 5+ $a = 4
デバッグ: ! SET $a = '4'.
デバッグ: 6+ $b = 5
デバッグ: ! SET $b = '5'.
デバッグ: 7+ $c = $a + $b
デバッグ: ! SET $c = '9'.
デバッグ: 8+ Write-Debug "Line8: $c"
上記を見るとわかるように、一番最初にスクリプトファイルの実行を行っているので
! CALL script 'Debug.ps1'
と表示されています。
また、変数に値がセットされるときは
SET $a = '2'.
のように表示されていることが分かります。
上記をまとめると-Traceは、どの行を通って来たかを確認するだけであれば「1」を、詳細情報(変数にセットされた情報、関数呼び出しなど)を得たい場合には「2」を指定すれば良いことが分かります。
未定義の変数を調査する
Set-PSDebugにパラメータ-Strictを指定することで、未定義の変数をエラーとして処理することができます。
下記のように、Set-PSDebugコマンドレットを-Strictパラメータを指定して実行し、値の代入されていない変数を参照しようとするとエラーになることが分かります。
PS > Set-PSDebug -Strict
PS > $a
変数 $a は、設定されていないために取得できません。
発生場所 行:1 文字:2
+ $a <<<<
また、下記スクリプト(「C:\Work\Strict.ps1」として保存)を準備し
$a = 3
Write-Host ($a + $b)
コマンドラインから実行すると
PS C:\Work> ./Strict.ps1
変数 $b は、設定されていないために取得できません。
発生場所 C:\Work\Strict.ps1:2 文字:20
+ Write-Host ($a + $b) <<<<
スクリプトファイル中の変数$bが値が設定されていないのに使用されたことをエラーとして報告します。
このように、-Strictパラメータを使用することで、未定義の変数を見つけることが可能です。
ステップ実行する
Set-PSDebugコマンドレットに-Stepパラメータを指定すると、ステップ実行を行うことが可能となります。「ステップ実行」は、スクリプトを1行ずつ停止させながら実行することができるモードです。
最初の方で紹介したDebug.ps1を用いて確認してみましょう。
コマンドラインで
PS C:\Work> Set-PSDebug -step; ./Debug.ps1
と入力して実行してみると、1行実行されるごとにメッセージが表示されます。
PS C:\Work> Set-PSDebug -step; ./Debug.ps1
この操作を続行しますか?
1+ Set-PSDebug -step; ./Debug.ps1
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ
(既定値は "Y"):
デバッグ: 1+ Set-PSDebug -step; ./Debug.ps1
「規定値は"Y"」と表示されている箇所がありますが、これは[Enter]キーを押すと次の行が押されることを意味しており、[Y]キーを押すのと同操作となります。
次に[Enter]を2回続けて入力し
この操作を続行しますか?
2+ $b = 3
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "Y"): s
というメッセージが表示されたところで[S]を入力します。
この状態で[S]を入力した場合には、処理が一時中断され、プロンプトの表示が
PS C:\Work>>>
に変わります。
ここで、プロントに下記のように$aと入力すると
PS C:\Work>>> $a
2
ステップ実行を行っている地点での変数の値を確認することができます(この場合は変数$aに2が代入されていることが分かります)。
プロンプトを終了して、デバッグを再会する場合には exit と入力します。
PS C:\Work>>> exit
ブレークポイントを使用する
ブレークポイントとは、プログラムの動作状態を確認するために、強制的に停止したい位置を設定する場所のことです。
ブレークポイントの設定は簡単で$host.EnterNestedPrompt()をブレークポイントをかけたい場所に記述するだけです。
Debug.ps1を下記のように改善してスクリプトにブレークポイントを設定し、実験してみたいと思います(5行目に挿入しました。スクリプトは「C:\Work\Debug.ps1」として上書き保存します)。)
$a = 2
$b = 3
$c = $a + $b
$host.EnterNestedPrompt() #ブレークポイントの設定
Write-Debug "Line4: $c"
$a = 4
$b = 5
$c = $a + $b
Write-Debug "Line8: $c"
上記を実行してみます。
PS C:\Work> ./Debug.ps1
デバッグ: Line4: 5
PS C:\Work>>>
上記のように、ブレークポイントを設定した位置までコードが実行されプロンプトが表示されます。
この状態は、「ステップ実行する」で説明した「中断処理」と同様で、変数の状態を確認することが可能です。試しに$a、$b、$cがどうなっているかみてみましょう。
PS C:\Work> ./Debug.ps1
デバッグ: Line4: 5
PS C:\Work>>> $a
2
PS C:\Work>>> $b
3
PS C:\Work>>> $c
5
PS C:\Work>>>
このようにブレークポイントを設定すると、ブレークポイントが設定された場所まで一気にコードが実行され、その時点での変数の値を確認することができます。プロンプトを終了するには exitと入力して[Enter]キーを押します。
PS C:\Work>>> exit
デバッグ: Line8: 9
PS C:\Work>
まとめ
今回は、PowerShellでのスクリプト開発におけるデバッグ機能について説明しました。
PowerShell自体にはVB.NETやC#のようにグラフィカルなデバッグ環境を持ち備えていません。しかし、今回紹介したデバッグ機能を用いることで、1行ずつステップ実行したり、変数の途中経過をウォッチすることが可能となります。
ぜひ、このデバッグ機能を有効に活用して、効率のよい開発を行っていただければ幸いです。
Windows PowerShell 入門(10)-デバッグ編的更多相关文章
- Windows PowerShell 入門(7)-関数編2
この連載では.Microsoftが提供している新しいシェル.Windows Power Shellの使い方を解説します.前回に引き続きPowerShellにおける関数の取り扱いとして.変数と関数のスコ ...
- Windows PowerShell 入門(2)-基本操作編 2
前回に引き続きMicrosoftが提供している新しいシェル.Windows Power Shellの基本操作方法を学びます.基本操作編第2弾の今回は.パイプの使用方法を中心としたコマンドレットの操作方 ...
- Windows PowerShell 入門(3)-スクリプト編
これまでの記事 Windows PowerShell 入門(1)-基本操作編 Windows PowerShell 入門(2)-基本操作編 2 対象読者 Windows PowerShellでコマンド ...
- Windows PowerShell 入門(8)-関数編3
この連載では.Microsoftが提供している新しいシェル.Windows PowerShellの使い方を解説します.今回は.フィルタ.スクリプトブロック.変数のスコープについて取り上げます. はじめ ...
- Windows PowerShell 入門(9)-エラー編
対象読者 Windows PowerShellでコマンドレット操作ができる方 何らかのプログラミング経験があればなお良い 必要環境 Windows PowerShell エラーをリダイレクトする リダ ...
- Windows PowerShell 入門(6)-関数編1
この連載では.Microsoftが提供している新しいシェル.Windows Power Shellの使い方を解説します.今回は.関数の作成基礎と引数.戻り値.Switchパラメータについて説明します. ...
- Windows PowerShell 入門(1)-基本操作編
Microsoftが提供している新しいシェル.Windows Power Shellの基本操作方法を学びます.インストール.起動終了方法.コマンドレット.命名規則.エイリアス.操作方法の調べ方について ...
- Windows PowerShell 入門(4)-変数と演算子
Windows PowerShellにおける変数と演算子の使用方法について学びます.今回は代表的な演算子として.算術演算子.代入演算子.論理演算子.比較演算子.範囲演算子.置換演算子.ビット演算子.型 ...
- Windows PowerShell 入門(5)-制御構文
Windows PowerShellにおける制御構文について学びます.数ある制御構文の中でもSwitch文は.他の言語に比べ豊富な機能が用意されています. 対象読者 Windows PowerShel ...
随机推荐
- python django基础一web框架的本质
web框架的本质就是一个socket服务端,而浏览器就是一个socker客户端,基于请求做出相应,客户端先请求,服务器做出对应响应 按照http协议的请求发送,服务器按照http协议来相应,这样的通信 ...
- Ubuntu 启动服务 失败 的 可能解决办法
➜ ~ service nfs-kernel-server start Job for nfs-server.service canceled. 如果遇到服务启动失败,请检查有关的文件夹是否创建( ...
- win7安装linux CentOS7双系统实践
开发需求要安装linux,百度了些资料,当然仅供参考,否则入坑. 步骤一 :制作Centos 7镜像文件,这步没什么坑 1.准备U盘8G以上 下载的话网上很多,这里提供一个下载路径: http:// ...
- 服务器SSL不安全漏洞修复方案
关于SSL POODLE漏洞 POODLE = Padding Oracle On Downgraded Legacy Encryption.是最新安全漏洞(CVE-2014-3566)的代号,俗称“ ...
- git步骤
1.New一个Repositories 2.拿到这个仓库的URL 3.git clone https://github.com/zhuobo/new.git 4.进入到clone下来的文件夹,然后gi ...
- tensorflow faster rann
github 上大神的代码 https://github.com/endernewton/tf-faster-rcnn.git 在自己跑的过程中的问题: 1. 数据集的问题: 作者实现了 voc,co ...
- Andrew NG 机器学习编程作业5 Octave
问题描述:根据水库中蓄水标线(water level) 使用正则化的线性回归模型预 水流量(water flowing out of dam),然后 debug 学习算法 以及 讨论偏差和方差对 该线 ...
- c# 读取excels
DataTable ExcelTable; DataSet ds = new DataSet(); //Excel 文件一般都保存为统一的xls的连接 其 ...
- 1.2 认识python(了解)
一.Python发展背景 Python的作者,Guido von Rossum(吉多·范·罗苏姆,中国Python程序员都叫他 龟叔),荷兰人.1982年,龟叔从阿姆斯特丹大学获得了数学和计算机硕士学 ...
- 集成JUnit测试错误java.lang.IllegalStateException: Failed to load ApplicationContext
1 详细错误信息 java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.t ...