PowerShell スクリプトで気をつけたい事
開発部の本橋です。 Windows でバッチ処理といえば cmd.exe ですが、cmd.exe で物足りない時に PowerShell を使う機会も増えてきました。PowerShell スクリプトを書く時に気をつけたい事をいくつか書いてみます。
推奨される Verb
PowerShell 標準のコマンドレットには 動詞-名詞
という命名規則があります。自分で function
を作る時にもこの命名規則に従っておくと他の人が使う時にもわかりやすくていいです。
さらに、動詞(Verb)の部分には推奨される単語があります。Get-Verb
コマンドレットで推奨される Verb を確認できます。
> Get-Verb Verb Group ---- ----- Add Common Clear Common Close Common Copy Common Enter Common Exit Common ...(略) # 使いたい Verb を引数に取ることもできる。 > Get-Verb Save Verb Group ---- ----- Save Data
動詞-名詞
の命名規則に従わなくても、さらには推奨される Verb を使わなくても別に良いのですが、ルールに則っておくと後々変な名前に悩まされることが少なくなります。
カレントディレクトリが2つある(ように見える)
pwd
(Get-Location
コマンドレットのエイリアス)で取得できるカレントディレクトリと、 .NET 側の API である[System.IO.Directory]::GetCurrentDirectory()
で取得できるカレントディレクトリが違います。
# カレントディレクトリは C:\Users\motohashi > pwd Path ---- C:\Users\motohashi # .NET で用意されている API を使っても同じ > [System.IO.Directory]::GetCurrentDirectory() C:\Users\motohashi # Cドライブの直下に移動するとカレントディレクトリは変わる > cd C:\ > pwd Path ---- C:\ # .NET で用意されている API を使うと変わっていない > [System.IO.Directory]::GetCurrentDirectory() C:\Users\motohashi
どうやらpwd
は現在のセッションのカレントディレクトリを返し、[System.IO.Directory]::GetCurrentDirectory()
は PowerShell プロセスのカレントディレクトリを返す、ということのようです。*1*2
これで何が困るかというと、.NET 側のクラスを使って相対パスでファイルを保存するようなケースです。
# 相対パスを指定してXMLファイルを読み込み # pwd で取得できるディレクトリからの相対パスとなる。 $xmldoc = [xml](cat 'path/to/xml') # ... xmlを変更 ... # 相対パスを指定してXMLファイルを書き込み # [System.IO.Directory]::GetCurrentDirectory() で取得できるディレクトリからの相対パスとなる。 $xmldoc.save('path/to/xml')
相対パスを使わずに絶対パスを使うようにするか、[System.IO.Directory]::SetCurrentDirectory()
で PowerShell プロセスのカレントディレクトリを変更するようにするといいですね。