Powershell에서 Native .tar 추출
나는 있습니다.tar.gz
추출해야 하는 파일입니다.▁withzip▁the▁gun로 건집 비트를 했습니다.GzipStream
의 입니다.System.IO.Compression
하지만 그 네임스페이스에서 타르볼을 다룰만한 것을 찾을 수 없었습니다.우리가 할 수 있는 일이.tar
Powershell에 있는 파일들?Powershell 스크립트에서 이러한 함수/메소드/객체 구성/시스템 바이너리를 호출할 수 있는 것만이 중요합니다. 실제로 Powershell로 작성할 필요는 없습니다. (중요한 경우 64비트 윈도우 10을 사용합니다.)
추신: "7zip 사용"이라고 말하지 마십시오. 그것은 네이티브가 아닙니다.
는 어요믿을 믿습니다.tar
는 이 게시물이 게시된 이후 Windows 10에 기본 기능으로 추가되었습니다.
명령 프롬프트 또는 Windows 10의 PowerShell에서 실행할 수 있습니다.
tar -xvzf .\whatever.tar.gz
로 고는 다음과 ..\
의 사용에 의해 자동 압축 해제된 후 추가되었습니다.tab
PowerShell에서, 하지만 그것 없이는 작동할 수 있다고 생각합니다.
이 기능과 유닉스 구현 사이에는 몇 가지 근본적인 차이점이 있을 수 있지만(결국 Windows에 있기 때문에) 저에게는 효과가 있었습니다.
2019년 업데이트:
다른 답변에서 지적했듯이 BSD tar는 2018년에 내장 명령어로 Windows 10에 추가되었습니다.이 대답은 이전 버전의 Windows(윈도우)를 지원해야 하는 경우에도 적용할 수 있습니다.
윈도우 10은 2018년 이전에는 기본적으로 tar 파일 추출을 지원하지 않았습니다.
Windows 10(초기 버전)을 위한 빠르고 간편한 솔루션
스크립트에 활성 인터넷 연결에 대한 액세스 권한이 있을 것으로 예상할 수 있는 경우 기본 패키지 관리자를 사용하여 7Zip 지원을 받을 수 있습니다.이 솔루션:
- 스크립트를 통해 완전히 자동화됨(사용자 작업 필요 없음)
- 관리자 권한이 필요하지 않음
- 7Zip 지원 모듈을 아직 사용할 수 없는 경우에만 설치합니다.
여기 있습니다.
function Expand-Tar($tarFile, $dest) {
if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
Install-Package -Scope CurrentUser -Force 7Zip4PowerShell > $null
}
Expand-7Zip $tarFile $dest
}
사용 방법:
Expand-Tar archive.tar dest
이는 작업을 수행하지만 클라이언트 시스템을 지속적으로 변경합니다.더 나은 솔루션이 있지만 조금 더 관련된 솔루션이 있습니다.
더 나은 해결책
더 나은 솔루션은 7Zip4를 번들로 제공하는 것입니다.스크립트와 함께 PowerShell에 액세스할 수 있습니다.이 솔루션:
- 스크립트를 통해 완전히 자동화됨(사용자 작업 필요 없음)
- 관리자 권한이 필요하지 않음
- 클라이언트 시스템에 소프트웨어를 설치하지 않음
- 인터넷 연결이 필요하지 않음
- 이전 버전의 Windows에서 작동해야 함
7Zip4 사본 다운로드PowerShell 패키지
LGPL-2.1 라이선스로 배포되므로 패키지를 제품과 함께 묶어도 괜찮습니다.GNU 라이센스 제품의 소스 코드에 대한 액세스 권한을 제공해야 하므로 문서에 패키지를 사용하고 링크를 제공한다는 내용의 참고 사항을 추가해야 합니다.
Save-Module -Name 7Zip4Powershell -Path .
그러면 현재 디렉터리로 다운로드됩니다.Windows 10에서 이 작업을 수행하는 것이 가장 쉽지만 위의 링크에서 이전 버전의 Windows에서 PowerShell Gallery를 시스템에 추가하는 방법에 대한 지침이 나와 있습니다.
tar 파일을 추출해야 할 때 모듈 가져오기
첫 번째 솔루션을 기반으로 이를 수행할 수 있는 방법을 보여주기 위해 간단한 기능을 만들었습니다.
function Expand-Tar($tarFile, $dest) {
$pathToModule = ".\7Zip4Powershell\1.9.0\7Zip4PowerShell.psd1"
if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
Import-Module $pathToModule
}
Expand-7Zip $tarFile $dest
}
$pathToModule
스크립트가 실행될 때 번들 모듈이 실제로 저장되는 위치로 이동하지만, 아이디어가 있어야 합니다.위의 두 코드 블록을 PowerShell 창에 붙여넣고 작업을 수행할 수 있도록 이 예제를 작성했습니다.Expand-Tar
cdlet:
Expand-Tar archive.tar dest
가능한 해결 방법:
윈도우 10을 실행하고 .curl
+tar
파워셸 내에서 하지만 지원이 부족했습니다.운 좋게도, 윈도우 10에서 Ubuntu bash를 실행했습니다.curl
그리고.tar
사전 설치되어 해당 환경에서 실행된 후 다운로드 및 압축 해제 후 Powershell로 다시 전환하여 작업을 계속했습니다.
또는 아래 설명에서 @Don Cruickshank가 언급한 대로 PowerShell 내에서 7zip 지원을 직접 설치할 수 있습니다.Install-Package 7Zip4Powershell
.Expand-7zip
은 tar.cmdlet tar와 여러 형식을 합니다.
이러한 해결 방법으로 특정 문제를 해결할 수는 없지만 Windows(윈도우)에 남아 있는 문제의 경우 유용할 수 있습니다.
로 윈도우 은 2017년에 출시되었습니다.tar
은 할 수 .exe
powershell
맘에 들다tar -xkf $archivePath -C $outDir
은혹더것은에서 더 .pwsh
.
시간이 좀 걸렸지만 제가 만든 해결책은 이렇습니다.기본적으로 TAR은 매우 간단한 형식이지만 처리하는 데는 몇 줄의 코드가 필요합니다.
Function ConvertTo-ByteString
{
Param(
[Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True )][byte[]]$Buffer
)
# Note: Codepage 28591 returns a 1-to-1 char to byte mapping
$Encoding = [System.Text.Encoding]::GetEncoding(28591)
#$BinaryText = [System.Text.Encoding]::Convert('ascii', '28591', $Buffer)
$BinaryText = [System.Text.Encoding]::ASCII.GetString($Buffer)
$BinaryText = $BinaryText.Trim(0)
$BinaryText = $BinaryText.Trim(32)
$BinaryText = $BinaryText.Trim(0)
$BinaryText = $BinaryText.Trim(32)
return $BinaryText
}
Function New-USTARHeaderObject
{
#Write-Host('[New-USTARHeaderObject]','Creating new header object') -ForegroundColor Cyan
$Header = New-Object -Type PSObject
$Header | Add-Member -MemberType NoteProperty -Name name -Value $null
$Header | Add-Member -MemberType NoteProperty -Name mode -Value $null
$Header | Add-Member -MemberType NoteProperty -Name uid -Value $null
$Header | Add-Member -MemberType NoteProperty -Name gid -Value $null
$Header | Add-Member -MemberType NoteProperty -Name size -Value $null
$Header | Add-Member -MemberType NoteProperty -Name mtime -Value $null
$Header | Add-Member -MemberType NoteProperty -Name cksum -Value $null
$Header | Add-Member -MemberType NoteProperty -Name typeflag -Value $null
$Header | Add-Member -MemberType NoteProperty -Name linkname -Value $null
$Header | Add-Member -MemberType NoteProperty -Name magic -Value $null
$Header | Add-Member -MemberType NoteProperty -Name version -Value $null
$Header | Add-Member -MemberType NoteProperty -Name uname -Value $null
$Header | Add-Member -MemberType NoteProperty -Name gname -Value $null
$Header | Add-Member -MemberType NoteProperty -Name devmajor -Value $null
$Header | Add-Member -MemberType NoteProperty -Name devminor -Value $null
$Header | Add-Member -MemberType NoteProperty -Name prefix -Value $null
return $Header
}
Function Fill-USTARHeaderObject
{
Param(
[Parameter(Mandatory=$True)][PSObject]$Header,
[Parameter(Mandatory=$True)][byte[]]$Buffer
)
#Write-Host('[Fill-USTARHeaderObject]','Filling header object with bytes') -ForegroundColor Cyan
$Header.name = [string](ConvertTo-ByteString $Buffer[0..99])
$Header.mode = ConvertTo-ByteString $Buffer[100..107]
$Header.uid = ConvertTo-ByteString $Buffer[108..115]
$Header.gid = ConvertTo-ByteString $Buffer[116..123]
$Header.size = ConvertTo-ByteString $Buffer[124..135]
$Header.mtime = ConvertTo-ByteString $Buffer[136..147]
$Header.cksum = ConvertTo-ByteString $Buffer[148..155]
$Header.typeflag = ConvertTo-ByteString $Buffer[156]
$Header.linkname = ConvertTo-ByteString $Buffer[157..256]
$Header.magic = ConvertTo-ByteString $Buffer[257..262]
$Header.version = ConvertTo-ByteString $Buffer[263..264]
$Header.uname = ConvertTo-ByteString $Buffer[265..296]
$Header.gname = ConvertTo-ByteString $Buffer[297..328]
$Header.devmajor = ConvertTo-ByteString $Buffer[329..336]
$Header.devminor = ConvertTo-ByteString $Buffer[337..344]
$Header.prefix = ConvertTo-ByteString $Buffer[345..499]
}
Function Check-IsUSTARHeaderObject
{
Param(
[Parameter(Mandatory=$True, Position = 0, ValueFromPipeline = $True)][PSObject]$Header
)
$Regex_Numeric = [regex]"^\d+$"
#Write-Host('[Check-IsUSTARHeaderObject]','Checking if object is actual header') -ForegroundColor Cyan
#Write-Host("[Mode ]",$Header.mode,($Regex_Numeric.Matches($Header.mode).Success)) -ForegroundColor Magenta
#Write-Host("[Size ]",$Header.size,($Regex_Numeric.Matches($Header.size).Success)) -ForegroundColor Magenta
#Write-Host("[MTime ]",$Header.mtime,($Regex_Numeric.Matches($Header.mtime).Success)) -ForegroundColor Magenta
#Write-Host("[CKSum ]",$Header.cksum,($Regex_Numeric.Matches($Header.cksum).Success)) -ForegroundColor Magenta
#Write-Host("[TypeFlag]",$Header.typeflag,($Regex_Numeric.Matches($Header.typeflag).Success)) -ForegroundColor Magenta
#Write-Host("[Magic ]",$Header.magic,($Header.magic -eq 'ustar')) -ForegroundColor Magenta
if (
($Regex_Numeric.Matches($Header.mode).Success) -and
($Regex_Numeric.Matches($Header.size).Success) -and
($Regex_Numeric.Matches($Header.mtime).Success) -and
($Regex_Numeric.Matches($Header.cksum).Success) -and
($Regex_Numeric.Matches($Header.typeflag).Success) -and
($Header.magic -eq 'ustar')
)
{
#Write-Host('[Check-IsUSTARHeaderObject]','TRUE') -ForegroundColor DarkCyan
return $true
} else {
#Write-Host('[Check-IsUSTARHeaderObject]','FALSE') -ForegroundColor DarkCyan
return $false
}
}
Function UnTar-File
{
Param(
[Parameter(Mandatory=$True)][String]$Source,
[Parameter(Mandatory=$False)][String]$Destination
)
#$Source = 'D:\temp\th-dfbase-blacklist.tar'
$SourceBaseName = (Get-Item $Source).BaseName
Write-Host('[UnTar-File]','Setting Source',$Source) -ForegroundColor Cyan
#if destination parameter not given
if ($Destination -eq "")
{
$SourcePath = Split-Path $Source
$OutFolder = Join-Path -Path $SourcePath -ChildPath $SourceBaseName
}
else
{
$OutFolder = Join-Path -Path $Destination -ChildPath $SourceBaseName
}
Write-Host('[UnTar-File]','Destination Folder',$OutFolder) -ForegroundColor DarkCyan
$FileStream = New-Object System.IO.FileStream $Source, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$BufferSize = 512
$Buffer = New-Object byte[]($BufferSize)
Write-Host('[UnTar-File]','Reading Source by', $BufferSize,'bytes') -ForegroundColor Cyan
while($true)
{
$read = $FileStream.Read($Buffer, 0, $BufferSize)
#Write-Host($read) -ForegroundColor Cyan
if ($read -le 0){break}
#Try Header
$Header = New-USTARHeaderObject
Fill-USTARHeaderObject -Header $Header -Buffer $Buffer
#if header section
if (Check-IsUSTARHeaderObject($Header))
{
$ItemPath = [IO.Path]::Combine($Header.prefix, $Header.name)
$ItemPath = $ItemPath.Replace('/','\')
#if folder type
if ($Header.typeflag -eq '5')
{
$FolderPath = Join-Path -Path $OutFolder -ChildPath $ItemPath
Write-Host('[UnTar-File]','Creating Folder',$FolderPath) -ForegroundColor Yellow
New-Item -Path $FolderPath -ItemType Directory -Force | Out-Null
}
#if file type
else
{
$FilePath = Join-Path -Path $OutFolder -ChildPath $ItemPath
Write-Host('[UnTar-File]','Creating File',$FilePath) -ForegroundColor DarkYellow
if ($OutputFile -ne $null)
{
$OutputFile.Close()
}
$OutputFileInfo = New-Object PSObject
$OutputFileInfo | Add-Member -MemberType NoteProperty -Name name -Value $Header.name
$OutputFileInfo | Add-Member -MemberType NoteProperty -Name path -Value (Split-Path -Path $FilePath)
$OutputFileInfo | Add-Member -MemberType NoteProperty -Name size -Value ([Convert]::ToInt32($Header.size, 8))
$OutputFileInfo | Add-Member -MemberType NoteProperty -Name left2write -Value ([Convert]::ToInt32($Header.size, 8))
$OutputFileInfo | Add-Member -MemberType NoteProperty -Name mtime -Value ([Convert]::ToInt32($Header.mtime, 8))
$OutputFile = New-Object System.IO.FileStream $FilePath, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
}
}
#if data section
else
{
if ($OutputFileInfo.left2write -ge $BufferSize)
{
$WriteSize = $read
} else {
$WriteSize = $OutputFileInfo.left2write
}
$OutputFile.Write($Buffer, 0, $WriteSize)
$OutputFileInfo.left2write = ($OutputFileInfo.left2write - $WriteSize)
}
}
$FileStream.Close()
if ($OutputFile -ne $null)
{
$OutputFile.Close()
}
}
UnTar-File -Source $Tar
그래서 제가 이것을 물어본 지 11일이 지났고 일반적인 합의는 "아니요, 바닐라 윈도우 설치에는 타르 추출을 '당신을 위해' 처리할 수 있는 네이티브 도구가 없습니다."입니다.
이 대답은 마티아스 R에서 나왔습니다. Jensen과 Tesellating Heckler는 둘 다 논평 외의 답변을 거부했습니다(전체 Windows 시스템 아키텍처에 대한 깊은 지식 없이는 "아니오"라고 말하고 싶지 않아서 그런 것 같습니다.).
설치할 수 있는 스크립트, 클래스 및 프로그램은 확실히 있지만 "네이티브"는 없습니다.
이 스니펫은 계속 작동합니다. 이 스니펫에서 사용하는 것이 설치되어 있지 않은 것 같습니다.이 타르를 뽑아내는 방법을 찾아야 해요
Function DeGZip-File{
Param(
$infile
)
$outFile = $infile.Substring(0, $infile.LastIndexOfAny('.'))
$input = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$output = New-Object System.IO.FileStream $outFile, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
$gzipStream = New-Object System.IO.Compression.GzipStream $input, ([IO.Compression.CompressionMode]::Decompress)
$buffer = New-Object byte[](1024)
while($true){
$read = $gzipstream.Read($buffer, 0, 1024)
if ($read -le 0){break}
$output.Write($buffer, 0, $read)
}
$gzipStream.Close()
$output.Close()
$input.Close()
}
$infile='D:\[Directory]\[File].tar.gz'
DeGZip-File $infile
다음은 PowerShell 스크립트의 일부입니다.
try
{
Add-Type -AssemblyName "ICSharpCode.SharpZLib"
$file = [IO.File]::OpenRead($gzArchiveName)
$inStream=New-Object -TypeName ICSharpCode.SharpZipLib.GZip.GZipInputStream $file
$tarIn = New-Object -TypeName ICSharpCode.SharpZipLib.Tar.TarInputStream $inStream
$archive = [ICSharpCode.SharpZipLib.Tar.TarArchive]::CreateInputTarArchive($tarIn)
$archive.ExtractContents($WORKDIR)
}
finally
{
$archive.Close
}
TarTool.exe 유틸리티의 코드에 해당합니다.
언급URL : https://stackoverflow.com/questions/38776137/native-tar-extraction-in-powershell
'source' 카테고리의 다른 글
pip가상 환경 대신 글로벌 사이트에 설치 (0) | 2023.08.17 |
---|---|
X-Requested-With 헤더 서버 검사가 Ajax 기반 애플리케이션의 CSRF로부터 보호하기에 충분합니까? (0) | 2023.08.17 |
:before 및 :before CSS 선택기를 사용하여 HTML 삽입 (0) | 2023.08.17 |
Heroku'Permission denied(공개 키)원격 저장소의 문제에서 읽을 수 없습니다. (0) | 2023.08.17 |
100vw로 인해 수평 오버플로가 발생하지만 하나 이상일 경우에만? (0) | 2023.08.17 |