programing

PowerShell에 임시 디렉토리를 생성하시겠습니까?

sourcejob 2023. 10. 21. 10:23
반응형

PowerShell에 임시 디렉토리를 생성하시겠습니까?

파워쉘 5는 편리한 cmdlet을 소개합니다.파일 대신에 디렉토리를 생성하는 동시에 동일한 작업을 수행하려면 어떻게 해야 합니까?있어요?New-TemporaryDirectorycmdlet?

디렉토리 이름에 GUID를 사용하면 루프 없이 수행할 수 있다고 생각합니다.

function New-TemporaryDirectory {
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    New-Item -ItemType Directory -Path (Join-Path $parent $name)
}

GetRandomFileName을(를) 사용한 원래 시도

C# 솔루션의 포트는 다음과 같습니다.

function New-TemporaryDirectory {
    $parent = [System.IO.Path]::GetTempPath()
    $name = [System.IO.Path]::GetRandomFileName()
    New-Item -ItemType Directory -Path (Join-Path $parent $name)
}

충돌 가능성 분석

그럴 가능성이 얼마나 됩니까?GetRandomFileName임시 폴더에 이미 존재하는 이름을 반환하시겠습니까?

  • 파일 이름이 양식으로 반환됩니다.XXXXXXXX.XXX여기서 X는 소문자 또는 숫자가 될 수 있습니다.
  • 비트 단위로 약 2^56인 36^11개의 조합을 제공합니다.
  • 생일 역설을 불러일으켜 폴더 내 약 2^28개 항목에 충돌이 발생할 것으로 예상됩니다. 약 3억 6천만 개입니다.
  • NTFS는 한 폴더에 2^32개의 항목을 지원하므로 다음을 사용하여 충돌이 발생할 수 있습니다.GetRandomFileName

NewGuid반면에 충돌을 거의 불가능하게 만드는 2^122의 가능성하나가 될 수 있습니다.

저도 한 줄을 사랑하고 여기서 반대표를 구걸하고 있습니다.제가 부탁하는 것은 당신이 이것에 대한 저만의 막연한 부정적인 감정을 말로 표현하는 것입니다.

New-TemporaryFile | %{ rm $_; mkdir $_ }

순수주의자의 유형에 따라 할 수 있습니다.%{ mkdir $_-d }, 충돌을 피하기 위해 자리 표시자를 남깁니다.

그리고 그 위에 서 있는 것이 합리적입니다.Join-Path $env:TEMP $(New-Guid) | %{ mkdir $_ }또한.

사용자 4317867의 답변을 변형한 것입니다.사용자의 Windows "Temp" 폴더에 새 디렉터리를 만들고 temp 폴더 경로를 변수로 사용할 수 있도록 합니다($tempFolderPath):

$tempFolderPath = Join-Path $Env:Temp $(New-Guid)
New-Item -Type Directory -Path $tempFolderPath | Out-Null

다음은 원라이너와 동일한 스크립트입니다.

$tempFolderPath = Join-Path $Env:Temp $(New-Guid); New-Item -Type Directory -Path $tempFolderPath | Out-Null

여기 완전한 임시 폴더 경로($tempFolderPath) 다음과 같습니다.

C:\Users\MassDotNet\AppData\Local\Temp\2ae2dbc4-c709-475b-b762-72108b8ecb9f

레이스와 충돌이 모두 없는 루프 솔루션을 원하는 경우, 여기에 있습니다.

function New-TemporaryDirectory {
  $parent = [System.IO.Path]::GetTempPath()
  do {
    $name = [System.IO.Path]::GetRandomFileName()
    $item = New-Item -Path $parent -Name $name -ItemType "directory" -ErrorAction SilentlyContinue
  } while (-not $item)
  return $item.FullName
}

Michael Kropat의 대답에서 분석한 바에 따르면, 대부분의 경우, 이것은 고리를 한 번만 통과할 것입니다.두 번이나 지나갈 일은 거의 없습니다.사실상 세 번은 지나가지 않을 것입니다.

제 시도는 이렇습니다.

function New-TemporaryDirectory {
    $path = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())

    #if/while path already exists, generate a new path
    while(Test-Path $path)) {
        $path = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
    }

    #create directory with generated path
    New-Item -ItemType Directory -Path $path
}

.NET은 해왔습니다.[System.IO.Path]::GetTempFileName()파일을 생성하고(및 이름 캡처) 파일을 삭제한 후 같은 이름의 폴더를 만들 수 있습니다.

$tempfile = [System.IO.Path]::GetTempFileName();
remove-item $tempfile;
new-item -type directory -path $tempfile;

저는 가능하면 한 대의 라이너를 좋아합니다.@알록의NET도 가지고 있습니다.[System.Guid]::NewGuid()

$temp = [System.Guid]::NewGuid();new-item -type directory -Path d:\$temp

Directory: D:\


Mode                LastWriteTime     Length Name                                                                                                                        
----                -------------     ------ ----                                                                                                                        
d----          1/2/2016  11:47 AM            9f4ef43a-a72a-4d54-9ba4-87a926906948  

당신이 원한다면, 당신은 매우 화려하고 윈도우 API 기능을 호출할 수 있습니다.GetTempPathA()다음과 같이:

# DWORD GetTempPathA(
#   DWORD nBufferLength,
#   LPSTR lpBuffer
# );

$getTempPath = @"
using System;
using System.Runtime.InteropServices;
using System.Text;

public class getTempPath {
    [DllImport("KERNEL32.DLL", EntryPoint = "GetTempPathA")]
    public static extern uint GetTempPath(uint nBufferLength, [Out] StringBuilder lpBuffer);
}
"@

Add-Type $getTempPath

$str = [System.Text.StringBuilder]::new()
$MAX_PATH = 260
$catch_res = [getTempPath]::GetTempPath($MAX_PATH, $str)
Write-Host $str.ToString() #echos temp path to STDOUT
# ... continue your code here and create sub folders as you wish ...
  1. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha

Michael Kropat의 답변에서 확장하기: https://stackoverflow.com/a/34559554/8083582

Function New-TemporaryDirectory {
  $tempDirectoryBase = [System.IO.Path]::GetTempPath();
  $newTempDirPath = [String]::Empty;
  Do {
    [string] $name = [System.Guid]::NewGuid();
    $newTempDirPath = (Join-Path $tempDirectoryBase $name);
  } While (Test-Path $newTempDirPath);

  New-Item -ItemType Directory -Path $newTempDirPath;
  Return $newTempDirPath;
}

이렇게 하면 충돌과 관련된 모든 문제가 제거됩니다.

언급URL : https://stackoverflow.com/questions/34559553/create-a-temporary-directory-in-powershell

반응형