Лучший способ проверить, существует ли путь или нет в PowerShell
мне просто не нравится синтаксис:
if (Test-Path $path) { ... }
и
if (-not (Test-Path $path)) { ... }
if (!(Test-Path $path)) { ... }
особенно есть слишком много скобок и не очень читается при проверке на "не существует" для такого общего использования. Что является лучшим способом сделать это?
обновление: мое текущее решение-использовать псевдонимы для exist
и not-exist
как пояснил здесь.
связанная проблема в репозитории PowerShell: https://github.com/PowerShell/PowerShell/issues/1970
3 ответа:
если вам просто нужна альтернатива синтаксису командлета, в частности для файлов, используйте
File.Exists()
.Чистый способ: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
решение псевдонимов, которое вы опубликовали, умно, но я бы возражал против его использования в скриптах, по той же причине, по которой мне не нравится использовать какие-либо псевдонимы в скриптах; это имеет тенденцию вредить читаемости.
Если это то, что вы хотите добавить в свой профиль, чтобы вы могли вводить быстрые команды или использовать его в качестве оболочки, тогда я мог бы увидеть, что это имеет смысл.
вместо этого вы можете рассмотреть трубопроводы:
if ($path | Test-Path) { ... } if (-not ($path | Test-Path)) { ... } if (!($path | Test-Path)) { ... }
альтернативно, для отрицательного подхода, если это уместно для ваш код, вы можете сделать его положительной проверкой, а затем использовать
else
для отрицательных: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)) { ... }