繁体   English   中英

从命令行将多个参数传递给Powershell函数?

[英]Pass multiple parameter to Powershell function from command line?

我正在编辑脚本函数以添加一个名为CloneGitPackage的函数。 这是我写的函数:

function CloneGitPackage {
    $PACKAGE_URL = $args[1]
    $PACKAGE_NAME = $args[2]

    write-verbose "Downloading package: $PACKAGE_URL $PACKAGE_NAME"
    git clone --depth 1 $PACKAGE_URL $PACKAGE_NAME 2>$null
    write-verbose ""
}

但是原始脚本还有其他一些功能:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

...

try{
    switch ($command){
        "bootstrap" { Bootstrap }
        "install" { Install }
        "run_tests" { RunTests }
        "clone_git_package" { CloneGitPackage }
    }
}catch {
    throw $_
}

我这样调用脚本:

 .\script.ps1 "clone_git_package" "https://github.com" "Folder" -verbose

但它在抱怨:

script.ps1 : A positional parameter cannot be found that accepts argument 'https://github.com'.
At line:1 char:19
+ ... .\script.ps1 "clone_git_package" "https://github.com/ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [script.ps1], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,script.ps1

Command executed with exception: A positional parameter cannot be found that accepts argument 'https://github.com'.

我以为问题是原始脚本已经有陌生人头了:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

这些是相应于其标头的对脚本的一些有效调用:

  1. .\\script.ps1 "bootstrap" -verbose
  2. .\\script.ps1 "install" -verbose
  3. .\\script.ps1 "run_tests" -coverage -verbose

我需要能够通过新函数名称调用脚本,在这种情况下为clone_git_package并提供其参数,字符串git URL和另一个字符串directory name

我该如何解决此问题,而又不破坏与已经使用此脚本的脚本上其他内容的向后兼容性?

为了能够将参数传递给函数,您将需要更新脚本的参数以适应您的其他参数。 因此,让我们从函数上的参数开始。 现在您参考:

$PACKAGE_URL = $args[1]
$PACKAGE_NAME = $args[2]

这不是特别好的脚本。 更好的选择是为函数创建实际参数:

function CloneGitPackage {
Param(
    $PACKAGE_URL,
    $PACKAGE_NAME
)

基本上,这与您之前所做的相同,因为参数的位置基于其列出的顺序。 我们可以做得更好,但实际上没有必要。 因此,如果我们将相同的逻辑应用于脚本的参数,它就会像这样(将开关保持在底部,使其成为最后一个期望的参数):

param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    $PACKAGE_URL,
    $PACKAGE_NAME,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

现在,当您向脚本提供其他信息时,该脚本便知道如何处理您的参数! 之后,您只需要更新脚本调用函数的方式,以在调用函数时包括那些参数,就可以了。

switch ($command){
    "bootstrap" { Bootstrap }
    "install" { Install }
    "run_tests" { RunTests }
    "clone_git_package" { CloneGitPackage $PACKAGE_URL $PACKAGE_NAME }
}

我做到了,它似乎运行良好:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false, Position = 1)]
    [string]$package_url,
    [Parameter(Mandatory = $false, Position = 2)]
    [string]$package_name,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

...

function CloneGitPackage {
    $PACKAGE_PATH = "$TARGET_FOLDER\$package_name"

    write-verbose "Downloading package: $package_url $PACKAGE_PATH"
    git clone --depth 1 $package_url $PACKAGE_PATH 2>$null
    write-verbose ""
}

try{
    switch ($command){
        "bootstrap" { Bootstrap }
        "install" { Install }
        "run_tests" { RunTests }
        "clone_git_package" { CloneGitPackage }
    }
}catch {
    throw $_
}

以以下方式调用时:

  1. .\\script.ps1 "bootstrap" -verbose
  2. .\\script.ps1 "install" -verbose
  3. .\\script.ps1 "run_tests" -coverage -verbose
  4. .\\script.ps1 "clone_git_package" "https://github.com" "Folder" -verbose

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM