PowerShell は、他のシェルスクリプト言語とは異なる独特の挙動を示すことがあり、一般的なシェル言語の感覚で実行すると、思わぬ落とし穴にはまることがあります。ここでは、PowerShell の罠となりうる要素をいくつかご紹介します。
int型へのキャストで小数点以下が切り捨てにならない。
多言語多くはint型へキャストでは切り捨てですが、PowerShell7はそうではありません。
例.
[int](6.6)
# 7 ⇐ 結果
[int](6.5)
# 6 ⇐ 結果
回避策
[Math]::Truncate(6.6)(6.6)
# 6 ⇐ 結果
こういうところで個性を出してくるのがMicrosoft
WindowsPowerShell(PowerShell5)のテキストファイルがBOM有
PowerShell7では解消されてUTF8のBOM無しになっている。
ただ、Windows11で標準インストールされているパワーシェルはWindowsPowerShell(PowerShell5)なので要注意

PowerShellのパイプはオブジェクトが渡せて、うまく使えばよいツールだと思うのですが、最後に出力するテキストファイルがBOM有と一般的ではないスタイルになっているあたりがMicrosoftらしいと思う。
ただ、Windows11で標準インストールされているパワーシェルはWindowsPowerShell(PowerShell5)なので要注意

PowerShellのOut-Fileで出力されるファイルがBOM有Unicodeで驚く
PowerShellのOut-Fileはパイプラインで繋ぐだけでファイルに出力してくれます。ファイルを開いたり閉じたりの手順が隠蔽されて、とてもPowerShell的で良いのですが、出来上がるテキストファイルがBOM有のUnicodeだった...
PowerShellのパイプはオブジェクトが渡せて、うまく使えばよいツールだと思うのですが、最後に出力するテキストファイルがBOM有と一般的ではないスタイルになっているあたりがMicrosoftらしいと思う。
代替案
PowerShell7をインストールし使う
コマンドの戻り値の要素が複数の場合と単数の場合でコードを分ける必要あり
例1.戻り値が変数になるケース
$result1 = Get-Process -Name notepad
($result1 -is [array])
# False ⇐ arrayでは無い = 変数
例2.戻り値がarrayになるケース
$result1 = Get-Process
($result1 -is [array])
# True ⇐ array
同じGet-Process
なのに結果が異なります。
動的型の言語だからと言ってこれはどうかと思います。変数ではなく要素が1つのarrayの方が一般的ではないでしょうか?
解決策
変数とarrayどちらも受け入れるコードを書きましょう。そうすると融通のきく素晴らしいスクリプトになります。(コードを書く側は大変ですか…)
感想
事前に知っておけば回避できますし、PowerShellの個性だと思って受け入れましょう。
コメント