プロジェクト

全般

プロフィール

PowerShellについて » 履歴 » リビジョン 6

リビジョン 5 (sylow castle, 2019/03/11 22:01) → リビジョン 6/7 (sylow castle, 2019/03/13 18:12)

# 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になります。 

 ### ExecutionPolicy 

 PowerShellスクリプトはデフォルトだと実行できません。繰り返します、デフォルトだと実行できません。 
 安全のため設定を変更する必要があります。確認は 

 ``` 
 Get-ExecutionPolicy 
 ``` 

 とりあえずローカルのものを動かせるようにするには、管理者権限でpowershell.exeを起動して以下のコマンドを打つ。 

 ``` 
 Set-ExecutionPolicy RemoteSigned 
 ``` 

 と思っていましたがそうでもないようです。 
 powershell.exeの起動時にオプションで「-ExecutionPolicy RemoteSigned」とか打ってあげればそのPowerShellプロセスだけRemoteSignedな権限で動かせるらしい。 

 より詳しくはこちら: 
 https://qiita.com/kikuchi/items/59f219eae2a172880ba6