事の顛末
先日からPowerShellにはまっている。好きではまっているわけではないのだけれど、動きがわからないと何かとよくはまる。今回は . で呼び出した.ps1ファイルのParam()が勝手に変わっていてはまった件。いや、勝手にというのは横柄なもの言いで、「コードがそうなっていたから」というのが正しいです。。
こんな感じで、パラメータ付きのスクリプトを作成して、その中から別のパラメータ付きのScript2.ps1を呼び出しているのだが。。。
Param([Parameter(Mandatory)][string]$SomeParam)
Write-Output $SomeParam
. ".\Script2.ps1"
Write-Output $SomeParam
Param([string]$SomeParam = $null)
PS C:\PowerShell> c:\PowerShell\Script1.ps1
value1
<- Script2.ps1によって、値を書き換えられてNULLになってしまっている。。。
Script2.ps1が呼び出された時に、$SomeParamがdefault valueである$nullで初期化されていたため、Script1.ps1に戻ってきたときには値が$nullになってしまっていた。コード書いているときには、Script2.ps1にデフォルトパラメータがあったことなど忘れていたので、なんで$nullになるのか意味不明??? あれれ???
結論
. で呼び出した .ps1 ファイルのスコープは呼び出し元と一緒なので、変数名が同じだと書き換わっちゃう。Param()で指定したパラメータ名も変数なので、動きは同じ。。。ということらしい。
で、どうしたか?
2つのScriptのうち、どちらかのパラメータ名を変更すればいいのだけど、パラメータの名前は.ps1を呼び出すときの名前付きパラメータとして表に出る名称なのでやたらと変更したくない。なので、こんな感じで内部変数にコピーしてしのぎました。(この変数名も結局、重なったら上書きされてしまうけどね)。
Param([Parameter(Mandatory)][string]$SomeParam)
$_someParam = $SomeParam # <- 別の変数にコピーしておく
Write-Output $_someParam
. ".\Script2.ps1"
Write-Output $_someParam