it-swarm.com.de

Eine bessere Möglichkeit, um zu überprüfen, ob ein Pfad in PowerShell vorhanden ist oder nicht

Ich mag nur nicht die Syntax von:

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

und

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

insbesondere gibt es zu viele Klammern, die bei der Überprüfung auf "nicht vorhanden" für eine solche häufige Verwendung nicht gut lesbar sind. Was ist ein besserer Weg, um dies zu tun?

Update: Meine derzeitige Lösung besteht darin, Aliase für exist und not-exist zu verwenden, wie hier .

Zugehöriges Problem im PowerShell-Repository: https://github.com/PowerShell/PowerShell/issues/197

87
orad

Wenn Sie nur eine Alternative zur Cmdlet-Syntax suchen, insbesondere für Dateien, verwenden Sie die .NET-Methode File.Exists():

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

Wenn Sie andererseits einen Alias ​​für einen allgemeinen Zweck für Test-Path negieren möchten, gehen Sie wie folgt vor:

# 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 verhält sich jetzt gena wie Test-Path, gibt aber immer das entgegengesetzte Ergebnis zurück:

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

Wie Sie sich bereits gezeigt haben, ist das Gegenteil ganz einfach, nur Alias ​​exists bis Test-Path:

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

Die von Ihnen gepostete Alias-Lösung ist clever, aber ich würde mich gegen die Verwendung in Skripten aussprechen, aus dem gleichen Grund, aus dem ich keine Aliase in Skripten verwende. es neigt dazu, die Lesbarkeit zu beeinträchtigen.

Wenn Sie dieses Element zu Ihrem Profil hinzufügen möchten, damit Sie Schnellbefehle eingeben oder es als Shell verwenden können, ist dies möglicherweise sinnvoll.

Sie könnten stattdessen Rohrleitungen in Betracht ziehen:

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

Alternativ können Sie für den negativen Ansatz, falls für Ihren Code zutreffend, eine positive Prüfung durchführen und dann else für das Negativ verwenden:

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

Fügen Sie die folgenden Aliase hinzu. Ich denke, diese sollten standardmäßig in PowerShell verfügbar gemacht werden:

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

Damit ändern sich die bedingten Anweisungen zu:

if (exist $path) { ... }

und

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

Eine andere Option ist die Verwendung von IO.FileInfo, wodurch Sie so viele Dateiinformationen erhalten, dass das Leben mit diesem Typ einfacher wird:

PS > mkdir C:\Temp
PS > dir C:\Temp\
PS > [IO.FileInfo] $foo = 'C:\Temp\foo.txt'
PS > $foo.Exists
False
PS > New-TemporaryFile | Move-Item -Destination C:\Temp\foo.txt
PS > $foo.Refresh()
PS > $foo.Exists
True
PS > $foo | Select-Object *


Mode              : -a----
VersionInfo       : File:             C:\Temp\foo.txt
                    InternalName:
                    OriginalFilename:
                    FileVersion:
                    FileDescription:
                    Product:
                    ProductVersion:
                    Debug:            False
                    Patched:          False
                    PreRelease:       False
                    PrivateBuild:     False
                    SpecialBuild:     False
                    Language:

BaseName          : foo
Target            : {}
LinkType          :
Length            : 0
DirectoryName     : C:\Temp
Directory         : C:\Temp
IsReadOnly        : False
FullName          : C:\Temp\foo.txt
Extension         : .txt
Name              : foo.txt
Exists            : True
CreationTime      : 2/27/2019 8:57:33 AM
CreationTimeUtc   : 2/27/2019 1:57:33 PM
LastAccessTime    : 2/27/2019 8:57:33 AM
LastAccessTimeUtc : 2/27/2019 1:57:33 PM
LastWriteTime     : 2/27/2019 8:57:33 AM
LastWriteTimeUtc  : 2/27/2019 1:57:33 PM
Attributes        : Archive

Weitere Details in meinem Blog.

2
VertigoRay