我知道我可以使用
rm -r -fo
在 PowerShell 中删除文件夹及其所有内容。但是有什么办法可以在 PowerShell 中使用 rm -rf
吗?
我尝试将以下脚本添加到我的
$Profile
中,但两者都不起作用。
第一次尝试:
function rm -rf() {
rm -r -fo
}
第二次尝试:
Set-Alias rm -rf "rm -r -fo"
按照评论中的建议,您可以编写一个代理函数,将
-rf
参数添加到 Remove-Item
。如果您随后将别名 rm
设置为指向您的代理函数而不是 Remove-Item
,您将能够像在 Unix 中一样使用 rm -rf MyDirectory
,同时仍然有机会使用 Remove-Item
的所有其他参数。您基本上将拥有 Remove-Item
和 additional 参数 -rf
。
如iRon 的优秀问答中所述,您可以使用以下命令生成代理函数体:
$MetaData = [System.Management.Automation.CommandMetaData](Get-Command Remove-Item)
[System.Management.Automation.ProxyCommand]::Create($MetaData)
这会给你:
[CmdletBinding(DefaultParameterSetName='Path', SupportsShouldProcess=$true, ConfirmImpact='Medium', SupportsTransactions=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=113373')]
param(
[Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]
${Path},
[Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
${LiteralPath},
[string]
${Filter},
[string[]]
${Include},
[string[]]
${Exclude},
[switch]
${Recurse},
[switch]
${Force},
[Parameter(ValueFromPipelineByPropertyName=$true)]
[pscredential]
[System.Management.Automation.CredentialAttribute()]
${Credential})
dynamicparam
{
try {
$targetCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters)
$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object { $_.Value.IsDynamic })
if ($dynamicParams.Length -gt 0)
{
$paramDictionary = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
foreach ($param in $dynamicParams)
{
$param = $param.Value
if(-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name))
{
$dynParam = [Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
$paramDictionary.Add($param.Name, $dynParam)
}
}
return $paramDictionary
}
} catch {
throw
}
}
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
$steppablePipeline.End()
} catch {
throw
}
}
<#
.ForwardHelpTargetName Microsoft.PowerShell.Management\Remove-Item
.ForwardHelpCategory Cmdlet
#>
您可以将其直接粘贴到您自己的函数定义中,您将已经拥有一个与
Remove-Item
相同的函数。
要添加参数
-rf
,请添加以下参数定义:
[switch]
$rf
如果不直接将其传递给
Remove-Item
,请将以下行添加到 dynamicparam
块中:
$PSBoundParameters.Remove('rf') | Out-Null
然后,当提供了
Remove-Item
参数时,您只需要处理 -rf
的调用即可。为此,请将行 $scriptCmd = {& $wrappedCmd @PSBoundParameters }
更改为:
if ($rf) {
$scriptCmd = {& $wrappedCmd @PSBoundParameters -Recurse -Force }
} else {
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
}
在下面的完整示例中,我将代理函数命名为
rm2
并进行了我已经描述过的所有更改。最后我打电话给 Set-Alias
以使其可用。不用担心,Set-Alias
只会影响您当前的会话,不会永久改变您的系统。您可以将以下块复制并粘贴到您的 PowerShell 配置文件中,每当您打开 PowerShell 会话时,您就可以使用 rm -rf
:
function rm2 {
[CmdletBinding(DefaultParameterSetName='Path', SupportsShouldProcess=$true, ConfirmImpact='Medium', SupportsTransactions=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=113373')]
param(
[Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]
${Path},
[Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
${LiteralPath},
[string]
${Filter},
[string[]]
${Include},
[string[]]
${Exclude},
[switch]
${Recurse},
[switch]
${Force},
[Parameter(ValueFromPipelineByPropertyName=$true)]
[pscredential]
[System.Management.Automation.CredentialAttribute()]
${Credential},
[switch]
$rf)
dynamicparam
{
try {
$PSBoundParameters.Remove('rf') | Out-Null
$targetCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters)
$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object { $_.Value.IsDynamic })
if ($dynamicParams.Length -gt 0)
{
$paramDictionary = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
foreach ($param in $dynamicParams)
{
$param = $param.Value
if(-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name))
{
$dynParam = [Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
$paramDictionary.Add($param.Name, $dynParam)
}
}
return $paramDictionary
}
} catch {
throw
}
}
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Remove-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
if ($rf) {
$scriptCmd = {& $wrappedCmd @PSBoundParameters -Recurse -Force }
} else {
$scriptCmd = {& $wrappedCmd @PSBoundParameters }
}
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
$steppablePipeline.End()
} catch {
throw
}
}
<#
.ForwardHelpTargetName Microsoft.PowerShell.Management\Remove-Item
.ForwardHelpCategory Cmdlet
#>
}
Set-Alias -Name rm -Value rm2 -Option AllScope