简体   繁体   English

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

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

I am editing a script function to add a function called CloneGitPackage . 我正在编辑脚本函数以添加一个名为CloneGitPackage的函数。 This is the function I wrote: 这是我写的函数:

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 ""
}

But the original script has some more other functions: 但是原始脚本还有其他一些功能:

[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 $_
}

I am calling the script like this: 我这样调用脚本:

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

But it is complaining: 但它在抱怨:

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'.

I supposed the problem is that stranger header the original script already have: 我以为问题是原始脚本已经有陌生人头了:

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

These are some valid calls to the script accordingly to its header: 这些是相应于其标头的对脚本的一些有效调用:

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

I need to be able to call the script passing the new function name, on this case clone_git_package and give its arguments, a string git URL and another string directory name . 我需要能够通过新函数名称调用脚本,在这种情况下为clone_git_package并提供其参数,字符串git URL和另一个字符串directory name

How can I fix this, without breaking backward compatibility with the other stuff on the script which already uses this stuff? 我该如何解决此问题,而又不破坏与已经使用此脚本的脚本上其他内容的向后兼容性?

In order to be able to pass parameters to your function you will need to update the script's parameters to accommodate your additional parameters. 为了能够将参数传递给函数,您将需要更新脚本的参数以适应您的其他参数。 So let's start with your parameters on your function. 因此,让我们从函数上的参数开始。 Right now you reference: 现在您参考:

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

This is not particularly good scripting. 这不是特别好的脚本。 A better option would be to create actual parameters for your function: 更好的选择是为函数创建实际参数:

function CloneGitPackage {
Param(
    $PACKAGE_URL,
    $PACKAGE_NAME
)

This essentially does the same thing you were doing before, since parameters are positional based on the order they are listed. 基本上,这与您之前所做的相同,因为参数的位置基于其列出的顺序。 We could get fancier, but really there's no need. 我们可以做得更好,但实际上没有必要。 So if we apply that same logic to the script's parameters it comes out like (keeping the switch at the bottom so that it's the last expected parameter): 因此,如果我们将相同的逻辑应用于脚本的参数,它就会像这样(将开关保持在底部,使其成为最后一个期望的参数):

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

Now the script knows what to do with your parameters when you give it the additional info! 现在,当您向脚本提供其他信息时,该脚本便知道如何处理您的参数! After that you just need to update how the script calls your function to include those parameters when it calls it, and you should be all set. 之后,您只需要更新脚本调用函数的方式,以在调用函数时包括那些参数,就可以了。

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

I did this, and it seemed to be working fine: 我做到了,它似乎运行良好:

[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 $_
}

When calling it as: 以以下方式调用时:

  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