PowerShellについて » 履歴 » バージョン 5
« 前 -
バージョン 5/7
(差分) -
次 » -
最新版
健二 酒井, 2019/03/11 22:01
PowerShellについて¶
概要¶
ボスがPowerShellで詰まっていたので自分なりの理解を説明するための記事
PowerShellを知らない人が以下の記事の「Code」を理解できるようになるのを目的にする:
PowerShell でウインドウの位置と大きさを指定
https://qiita.com/yumura_s/items/f6fa9dbeb5c6c4b6e4fb
読めない¶
独特な書き味があって知らないと辛いことが多い。
シェルスクリプトの一種だと意識すると読みやすくなるかも。(でも中身の仕組み的には結構違うっぽい(後述))
パイプを通して各コマンドにデータを一つずつ渡していくような考え方は近いと思う
コツ¶
上記記事のコードの場合、以下を意識すると良いかな。
- 「fileter」は「function」と読み替える。実際、filterは特殊なfunctionでしかない。
- %はforeachと読む。パイプで渡された各オブジェクトに対し{}ブロック内の処理を実行する
- C#のコードは無視する。それでもやりたいことは分かる。
- 各コマンドはオブジェクトが渡され、オブジェクトを出力
- 変数やリテラルだけの行は「Write-Output 変数やリテラル」と読む。$rc2は「Write-Output $rc2」と読む。Write-Outputは後述。
上記記事に書かれている「Code」は関数の定義だけ書かれてる感じになる。
bashでスクリプトをインクルードするときの同じく「. psスクリプト」で実行してあげたら、現在のコンテキストで実行してくれるので関数のインクルードがされる。
PowerShellの気持ち¶
bashと比較¶
bashの場合はパイプを通して各コマンドに文字列が渡されて、各コマンドが改行で区切って1つのレコードと処理してる感じ。
PowerShellの場合は、コマンドや関数がパイプというキューからデータ一個取り出して、処理したデータを後続のパイプ(キュー)に出している感じ。
一つの長大な文字列をパースしながら処理単位を切り出しているのがbashだけど、PowerShellの場合シェル側で各データを分けて考えられてるのは大きな違い。
ただ、どちらも各コマンド・コマンドレットは、1つの単位でデータを処理して後続に渡しているイメージは共通だと思う。
Write-Outputと省略¶
Write-Outputコマンドレットは後続のパイプに出力する関数。
また、上の「コツ」に書いた通り「変数」だけ書かれた行は「Write-Output 変数」となり、パイプに出力をしていることになる。
この書き方のおかげでPowerShellの関数(function、filter)は、「引数をもらって値を一つ返す」という通常の言語の「関数」ではなくて、
パイプからデータ取り出して後ろのパイプにデータを垂れ流していく存在と考えるほうが近い気がする。
PowerShellにおいて「return」は処理を止める程度の意味合いしかない。
Out-Nullコマンドレット¶
「Out-Null」はbashでいう/dev/nullへのリダイレクトのようなイメージ、出力したオブジェクトはその流れから消滅する。
%とforeach¶
%{Get-WindowRect $_.Name}
で書かれている$_はコマンドレットが受け取ったオブジェクト1個を表す変数。
まとめて扱う訳じゃなくて一個一個に対して処理をしている。
行き場のないオブジェクト¶
パイプから入って次のパイプに出していると考えると、最後のコマンドから出力されるオブジェクトは行き場がなくなる。
行き場がないオブジェクトは実行してコンソールに出力される。
デフォルトの行先がコンソールになるだけなので、パイプに出力せずコンソールに出力することは可能(それがWrite-Hostコマンドレット)
仕様¶
function¶
PowerShellの関数は3つの処理ブロックを持つ。各オブジェクトが渡される前後に一度だけ実行されるBegin、Endブロックと各オブジェクトに対して実行されるProcessブロック。
filterはProcessブロックだけからなるfunctionになります。