如何解决在powershell中制作别名的最简单方法是什么?
我想知道是否有任何简单的方法可以为 cmd 之类的 powershell 制作别名。
例如:在 cmd 中,doskey art=php artisan $*
其中 $*
是可选的。目前,我在 powershell 中使用以下别名。
function runArtisanCommand
{
param(
[Parameter(Mandatory=$false,Position = 0,ValueFromRemainingArguments = $true)]
$command
)
php artisan $command
}
Set-Alias art runArtisanCommand
这有点作用,但不带标志。例如:我不会写 art -h
或 art route:list -c
。在 art -h
命令中,它打印 php artisan
的输出并且根本不读取标志,但在 art route:list -c
命令中,它会出错。
runArtisanCommand : Missing an argument for parameter 'command'. Specify a parameter of type 'System.Object' and try again.
At line:1 char:16
+ art route:list -c
+ ~~
+ CategoryInfo : InvalidArgument: (:) [runArtisanCommand],ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,runArtisanCommand
我想要一个比这更简单的解决方案。提前致谢。
解决方法
传递未知参数的最简单、最方便的方法是通过 spatting
automatic $args
array - 作为 @args
- 在简单函数或脚本中(既不使用 [CmdletBinding()]
也不使用 [Parameter()]
属性) :
# Note: @args rather than $args makes the function work with named
# arguments for PowerShell commands too - see explanation below.
function runArtisanCommand { php artisan @args }
# As in your question: Define alias 'art' for the function
# Note: Of course,you could directly name your *function* 'art'.
# If you do want the function to have a longer name,consider one
# that adheres to PowerShell's Verb-Noun naming convention,such as
# 'Invoke-ArtisanCommand'.
Set-Alias art runArtisanCommand
顺便说一句:由于目标可执行文件 php
既没有引用,也没有基于变量或表达式指定,它可以是按原样调用;否则,您将需要 &
,call operator - 有关背景信息,请参阅 this answer。
至于你尝试了什么:
问题是使用 -c
作为 pass-through 参数只有在它前面加上 --
时才有效:
# OK,thanks to '--'
art -- route:list -c
--
告诉 PowerShell 将所有剩余参数视为 未命名(位置)参数,而不是尝试将 -c
等标记解释为参数名称 em>.
如果没有 --
,-c
被解释为引用您的 -command
参数(您声明为 $command
并带有 {{1} }),前提是 PowerShell 允许您指定名称 前缀 代替完整的参数名称,只要给定的前缀是明确的。
因为除 ValueFromRemainingArguments = $true
之外的任何类型的参数都需要一个关联的参数,[switch]
(又名 -c
)失败并显示错误消息。
您可以通过命名参数来避免冲突,使其不会与任何传递参数发生冲突,例如将其命名为 -command
(使用参数变量 {{ 1}}):
-_args
但是,鉴于使用 $_args
属性隐式地使您的函数成为 advanced 函数,它总是也接受 common parameters,例如function runArtisanCommand
{
param(
# Note: `Mandatory = $false` and `Position = 0` are *implied*.
[Parameter(ValueFromRemainingArguments)]
$_args
)
php artisan @_args
}
,[Parameter()]
,-ErrorAction
... - 所有这些都可以通过明确的前缀/短别名传递;例如,-OutVariable
代表 -Verbose
,或别名 -outv
代表 -OutVariable
; 无法避免与他们发生冲突。
因此,诸如 -ea
still 之类的预期传递参数将不起作用:
ErrorAction
同样需要 -e
:
# FAILS,because -e ambiguously matches common parameters -ErrorAction
# and -ErrorVariable.
PS> art router:list -e
Parameter cannot be processed because the parameter name 'e' is ambiguous.
Possible matches include: -ErrorAction -ErrorVariable.
总结:
-
特别是对于函数包装对外部程序的调用,例如
--
,使用带有{的简单函数{1}},如顶部所示,不仅更简单,而且更强大。 -
对于封装 PowerShell 命令的函数(带有明确声明的参数):
- 一个带有
# OK,thanks to '--' art -- router:list -e
的简单函数也可以, - 但如果您还希望支持制表符补全并显示带有支持参数的 syntax diagram,请通过传递
php.exe
或通过Get-Help
,考虑通过 PowerShell SDK 定义(总是高级)代理(包装器)函数 - 见下文。
- 一个带有
可选背景信息:PowerShell 中的传递参数
正如 Mathias R. Jessen 指出的那样,将传递给函数或脚本的(未声明的)参数通过传递给另一个命令的最简单方法是使用 automatic $args
variable ,这是一个自动填充的数组,包含所有传递给 简单 函数或脚本的参数(不是 advanced,通过使用 @args
和/或 @args
属性)。
至于为什么应该使用-?
(喷溅)而不是[CmdletBinding()]
:
-
在包装函数中按原样使用
[Parameter()]
仅适用于传递 位置 参数(那些没有以参数名称为前缀的参数;例如,@args
) ,而不是 named 参数(例如,$args
)。 -
如果最终目标命令是一个外部程序(例如本例中的
$args
),这不是问题,因为 PowerShell 必然会处理 all 参数作为位置参数(它无法知道目标程序的语法)。 -
但是,如果最终调用 PowerShell 命令(带有正式声明的参数),则只有 splatting
*.txt
数组 - 这在语法上意味着我们 {{ 1}} 代替 - 支持通过 named 参数传递。[1]
因此,作为一种习惯,我建议总是在简单的包装函数中使用 -Path *.txt
,这同样适用于外部程序。[2]
举一个带有 Get-ChildItem
的简单包装函数的例子:
php.exe
使用代理函数进行更复杂的传递处理:
$args
的使用很方便,但代价是不支持以下内容:
-
制表符补全,鉴于制表符补全仅适用于正式声明的参数(通常使用
@args
块)。 -
显示带有支持参数的 syntax diagram,通过传递
@args
或通过Get-Help
为了克服这些限制,最终目标命令的参数声明必须在(然后是高级的)包装函数中复制;虽然这很麻烦,但 PowerShell 可以通过 PowerShell SDK 搭建所谓的代理(包装器)函数,从而自动执行该过程 - 请参阅this answer。
注意:
-
对于诸如
# Simple wrapper function for Get-ChildItem that lists recursively # and by relative path only. function dirTree { # Use @args to make sure that named arguments are properly passed through. Get-ChildItem -Recurse -Name @args } # Invoke it with a *named* argument passed through to Get-ChildItem # If $args rather than @args were used inside the function,this call would fail. dirTree -Filter *.txt
之类的常见参数,是代理函数本身(自动)处理它们,但这不会对调用者产生影响. -
脚手架代理功能仅适用于 PowerShell 命令,因为 PowerShell 不了解外部程序的语法。
- 但是,您可以手动复制外部目标程序的参数声明。
[1] 请注意,自动 @args
数组具有支持此功能的内置魔法;自定义数组不支持使用 splatting 传递命名参数,需要使用 hash table 代替,如上面链接的关于 splatting 的帮助主题中所述.
[2] 其实只有param(...)
也支持正确解释-?
,即stop-parsing symbol。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。