在PowerShell中创建一个临时目录?

Mic*_*pat 26 powershell temporary-directory

PowerShell 5引入了New-TemporaryFilecmdlet,非常方便.我怎样才能做同样的事情而不是文件创建目录?有New-TemporaryDirectorycmdlet吗?

Mic*_*pat 41

我认为通过使用目录名称的GUID可以在不循环的情况下完成:

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

GetRandomFileName的原始尝试

这是我的C#解决方案的端口:

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

碰撞可能性分析

GetRandomFileName返回temp文件夹中已存在的名称的可能性有多大?

  • 文件名以XXXXXXXX.XXXX可以是小写字母或数字的形式返回.
  • 这给了我们36 ^ 11个组合,其中比特大约是2 ^ 56
  • 调用生日悖论,一旦我们到达文件夹中的大约2 ^ 28项,我们就会发生碰撞,这大约是3.6亿
  • NTFS支持一个文件夹中大约2 ^ 32个项目,因此可以使用它进行冲突GetRandomFileName

NewGuid另一方面,可能是2 ^ 122种可能性中的一种,使得碰撞几乎不可能.

  • 如果你的临时文件夹中有3.6亿个项目,我认为你遇到的问题比某些PS脚本由于名称冲突而失败有更大的问题. (7认同)
  • 我可能会将 `GetRandomFileName()` 和 `New-Item` 放入循环中,以便在名称冲突时自动重试。 (2认同)

nik*_*kov 18

我也喜欢单行,我在这里求助.我要问的是,你把我自己模糊的负面情绪写成了文字.

New-TemporaryFile | %{ rm $_; mkdir $_ }
Run Code Online (Sandbox Code Playgroud)

根据您的纯粹主义者的类型,您可以这样做%{ mkdir $_-d },留下占位符以避免碰撞.

站在上面Join-Path $env:TEMP $(New-Guid) | %{ mkdir $_ }也是合理的.

  • 对我来说似乎是一个很好的单行.除非另有证明,否则我认为竞争条件的可能性很小,但99%的用例并不是真正的问题. (3认同)
  • 请注意,正如 Raymond Chen 在 https://blogs.msdn.microsoft.com/oldnewthing 的“异步复制和删除的情况”中所暗示的那样,我已经看到“删除和重新创建”策略在使用慢速防病毒软件的系统上失败/20120907-00/?p=6663。 (3认同)
  • 这是“本机 PowerShell”变体:`New-TemporaryFile | % { 删除项目 $_; 新项目 -ItemType 目录 -Path $_ }` (2认同)

Mas*_*Net 11

这是 user4317867's answer的变体。我在用户的 Windows“ Temp ”文件夹中创建一个新目录,并使临时文件夹路径可用作变量 ( $tempFolderPath):

$tempFolderPath = Join-Path $Env:Temp $(New-Guid)
New-Item -Type Directory -Path $tempFolderPath | Out-Null
Run Code Online (Sandbox Code Playgroud)

以下是单行可用的相同脚本:

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

这是完全限定的临时文件夹路径 ( $tempFolderPath) 的样子:

C:\Users\MassDotNet\AppData\Local\Temp\2ae2dbc4-c709-475b-b762-72108b8ecb9f
Run Code Online (Sandbox Code Playgroud)


Joh*_*man 8

如果您想要保证既无竞争又无碰撞的循环解决方案,那么这里是:

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
}
Run Code Online (Sandbox Code Playgroud)

根据Michael Kropat 的回答中的分析,绝大多数情况下,这只会通过循环一次。很少会通过两次。几乎永远不会通过三遍。