如何防止函数和变量名冲突?

时间:2014-09-12 21:24:16

标签: powershell

我正在编写一个脚本来安装多个程序。

Install.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$here\includes\script1.ps1"
. "$here\includes\script2.ps1"

Write-Host "Installing program 1"

Install-ProgramOne

Write-Host "Installing program 2"

Install-ProgramTwo

script1.ps1

param (
    [string] $getCommand = "msiexec /a program1.msi /q"
)

function Get-Command {
    $getCommand
}

function Install-ProgramOne {
    iex $(Get-Command)
}

script2.ps1

param (
    [string] $getCommand = "msiexec /a program2.msi /q"
)

function Get-Command {
    $getCommand
}

function Install-ProgramTwo {
    iex $(Get-Command)
}

当包含两个文件时,$getCommand变量将被覆盖。

C#中有名称空间,Ruby中有模块,但我无法弄清楚如何在Powershell中保持名称空间分开。

2 个答案:

答案 0 :(得分:1)

$getCommand变量不是变量本身,而是参数。指定了默认值的参数。也就是说,为点源脚本文件提供脚本参数并不是一个好主意。这些类型的文件通常只包含函数库和共享/全局变量。

V2和更高版本中更好的方法是使用模块。模块是变量和函数的容器,您可以在其中控制导出的内容和私有内容。这就是我对你的两个脚本所做的事情:

script1.psm1

# private to this module
$getCommand = "msiexec /a program1.msi /q"

function Get-Command {
    $getCommand
}

function Install-ProgramOne {
    iex $(Get-Command)
}

Export-ModuleMember -Function Install-ProgramOne 

script2.psm1

# private to this module
$getCommand = "msiexec /a program2.msi /q"

function Get-Command {
    $getCommand
}

function Install-ProgramTwo {
    iex $(Get-Command)
}

Export-ModuleMember -Function Install-ProgramTwo

使用方式如下:

Import-Module $PSScriptRoot\script1.psm1
Import-Module $PSScriptRoot\script2.psm1

Install-ProgramOne
Install-ProgramTwo 

答案 1 :(得分:0)

你是"点源"你的脚本而不是运行它们。这基本上意味着"将所有内容转储到GLOBAL名称空间"。如果你只是运行脚本而不是点源它们,那么它们每个都有自己的局部范围。一般来说,我认为应该运行带参数的脚本,而不是点源。

非点源的问题在于,默认情况下,您声明的功能将在脚本完成时超出范围。为避免这种情况,您可以改为定义您的函数:

function global:Install-ProgramOne
{

}

然后只运行脚本而不是dot-sourcing,$ getcommand将是您运行的每个脚本的本地脚本。