[powershell] 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



답변

특히 파일에 대한 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

이미 자신을 보여준 것처럼, 반대, 아주 쉽게 바로 별칭 existsTest-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)) { ... }


답변

또 다른 옵션은 IO.FileInfo이렇게 많은 파일 정보를 제공하여이 유형을 사용하는 것만으로도 쉽게 사용할 수 있습니다.

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

내 블로그에 대한 자세한 내용.


답변

경로가 디렉토리에 있는지 확인하려면 다음을 사용하십시오.

$pathToDirectory = "c:\program files\blahblah\"
if (![System.IO.Directory]::Exists($pathToDirectory))
{
 mkdir $path1
}

파일 경로가 있는지 확인하려면 @Mathias가 제안한 것을 사용하십시오.

[System.IO.File]::Exists($pathToAFile)


답변

이것이 내 powershell 초보자 방법입니다.

if ((Test-Path ".\Desktop\checkfile.txt") -ne "True") {
    Write-Host "Damn it"
} else {
    Write-Host "Yay"
}


답변