在PowerShell中检查path是否存在的更好的方法

我只是不喜欢的语法:

if (Test-Path $path) { ... } 

 if (-not (Test-Path $path)) { ... } if (!(Test-Path $path)) { ... } 

尤其是在检查“不存在”这种常见用法时,括号太多,不易读。 什么是更好的方法来做到这一点?

更新:我目前的解决scheme是使用别名existnot-exist , 这里解释。

PowerShell存储库中的相关问题: https : //github.com/PowerShell/PowerShell/issues/1970

如果您只想要替代cmdlet语法(特别是文件),请使用File.Exists() NET方法:

 if(![System.IO.File]::Exists($path)){ # file with path $path doesn't exist } 

另一方面,如果你想要一个通用的否定Test-Path别名,这里是你应该怎么做:

 # Gather command meta data from the original Cmdlet (in this case, Test-Path) $TestPathCmd = Get-Command Test-Path $TestPathCmdMetaData = New-Object System.Management.Automation.CommandMetadata $TestPathCmd # Use the static ProxyCommand.GetParamBlock method to copy # Test-Path's param block and CmdletBinding attribute $Binding = [System.Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($TestPathCmdMetaData) $Params = [System.Management.Automation.ProxyCommand]::GetParamBlock($TestPathCmdMetaData) # Create wrapper for the command that proxies the parameters to Test-Path # using @PSBoundParameters, and negates any output with -not $WrappedCommand = { try { -not (Test-Path @PSBoundParameters) } catch { throw $_ } } # define your new function using the details above $Function:notexists = '{0}param({1}) {2}' -f $Binding,$Params,$WrappedCommand 

notexists现在的行为与Test-Path 完全相同 ,但总是返回相反的结果:

 PS C:\> Test-Path -Path "C:\Windows" True PS C:\> notexists -Path "C:\Windows" False PS C:\> notexists "C:\Windows" # positional parameter binding exactly like Test-Path False 

正如你已经展示过的,反过来很容易,只是别名exists Test-Path

 PS C:\> New-Alias exists Test-Path PS C:\> exists -Path "C:\Windows" True 

你发布的别名解决scheme是聪明的,但我会反对它在脚本中的使用,出于同样的原因,我不喜欢在脚本中使用任何别名; 它往往会损害可读性。

如果这是你想要添加到你的configuration文件,所以你可以input快速命令或使用它作为一个shell,那么我可以看到这是有道理的。

你可能会考虑pipe道而不是:

 if ($path | Test-Path) { ... } if (-not ($path | Test-Path)) { ... } if (!($path | Test-Path)) { ... } 

或者,对于否定的方法,如果适合您的代码,您可以使其为正面检查,然后使用否定的否定:

 if (Test-Path $path) { throw "File already exists." } else { # The thing you really wanted to do. } 

添加以下别名。 我认为这些应该默认在PowerShell中可用:

 function not-exist { -not (Test-Path $args) } Set-Alias !exist not-exist -Option "Constant, AllScope" Set-Alias exist Test-Path -Option "Constant, AllScope" 

这样,条件语句将变为:

 if (exist $path) { ... } 

 if (not-exist $path)) { ... } if (!exist $path)) { ... }