1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

. で呼び出した.ps1ファイルの変数のScopeは呼び出し元と同じなんですね(Parameterも)。

Last updated at Posted at 2019-09-04

事の顛末

先日からPowerShellにはまっている。好きではまっているわけではないのだけれど、動きがわからないと何かとよくはまる。今回は . で呼び出した.ps1ファイルのParam()が勝手に変わっていてはまった件。いや、勝手にというのは横柄なもの言いで、「コードがそうなっていたから」というのが正しいです。。

こんな感じで、パラメータ付きのスクリプトを作成して、その中から別のパラメータ付きのScript2.ps1を呼び出しているのだが。。。

Script1.ps1
Param([Parameter(Mandatory)][string]$SomeParam)
Write-Output  $SomeParam
. ".\Script2.ps1"
Write-Output $SomeParam
Script2.ps1
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を呼び出すときの名前付きパラメータとして表に出る名称なのでやたらと変更したくない。なので、こんな感じで内部変数にコピーしてしのぎました。(この変数名も結局、重なったら上書きされてしまうけどね)。

Script1.ps1
Param([Parameter(Mandatory)][string]$SomeParam)
$_someParam = $SomeParam # <- 別の変数にコピーしておく
Write-Output  $_someParam
. ".\Script2.ps1"
Write-Output $_someParam

参考文献

PowerShell のスコープ完全に理解した

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?