압축 해제의 입력으로 wget의 출력을 리디렉션하는 방법은 무엇입니까?


131

링크 에서 파일을 다운로드해야합니다 . 파일 다운로드는 현재 폴더에서 압축을 풀어야하는 zip 파일입니다.

일반적으로 먼저 다운로드 한 다음 unzip 명령을 실행합니다.

$ wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip
$ unzip temp.zip

그러나이 방법으로, 나는,이 명령을 실행 또한, 내가 파일의 이름을 알고 있어야합니다, 다음 중 하나를 실행하는 첫 번째의 완료를 기다릴 필요 temp.zip에 제공하기를 unzip.

의 출력을 wget로 리디렉션 할 수 unzip있습니까? 같은 것

$ unzip < `wget http://www.vim.org/scripts/download_script.php?src_id=11834`

그러나 작동하지 않았습니다.

bash : wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip: 모호한 리디렉션

또한 wget두 번 실행되어 파일을 두 번 다운로드했습니다.


후자의 예에서, wget은? 쉘의 특수 문자입니다. ""에 URL을 넣으면 도움이됩니다.
p-static

이 스레드에는 해결책이있는 것 같습니다. 그래도 직접 시도하지 않았습니다. serverfault.com/questions/26474/…

답변:


96

unzip 매뉴얼 페이지를 인용하여 임시 파일로 파일을 다운로드해야합니다.

funzip을 제외하고 표준 입력에서 읽은 아카이브는 아직 지원되지 않으며 아카이브의 첫 번째 멤버 만 추출 할 수 있습니다.

명령을 함께 가져 오십시오.

wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip; unzip temp.zip; rm temp.zip

그러나 좀 더 융통성있게 만들려면 스크립트에 넣어서 입력 내용을 저장하고 실수로 덮어 쓰지 않도록 mktemp명령을 사용하여 임시 파일의 안전한 파일 이름을 만들 수 있습니다 .

#!/bin/bash
TMPFILE=`mktemp`
PWD=`pwd`
wget "$1" -O $TMPFILE
unzip -d $PWD $TMPFILE
rm $TMPFILE

wget file.zip && unzip file.zip는 동일 wget file.zip; unzip file.zip하거나 하나는 다른 선호한다? 감사합니다 :)
jaggedsoft

7
@NextLocal wget && unzip은 wget이 성공한 경우에만 압축 해제를 실행합니다. wget ; unzip어쨌든 압축 해제를 실행하여 존재하지 않는 파일을 가리킬 수 있습니다.
temoto

funzip은 내가 찾던 답변이었습니다. Terraform (어떤 이유로 든) 패키지는 zip 아카이브의 단일 파일로 바이너리이므로 패키지가 완벽했습니다.
Asfand Qazi

74

이것은 비슷한 질문에 대한 나의 대답 을 다시 게시 한 것입니다 .

ZIP 파일 형식은 아카이브 끝에 디렉토리 (인덱스)를 포함합니다. 이 디렉토리는 아카이브 내에서 각 파일의 위치를 ​​알려주므로 전체 아카이브를 읽지 않고도 신속하고 무작위로 액세스 할 수 있습니다.

이것은 파이프를 통해 ZIP 아카이브를 읽으려고 할 때 문제가있는 것으로 보입니다. 인덱스는 끝까지 액세스 할 수 없으므로 파일을 완전히 읽은 후 더 이상 사용할 수 없을 때까지 개별 멤버를 올바르게 추출 할 수 없습니다. . 따라서 아카이브를 파이프를 통해 공급할 때 대부분의 ZIP 압축 풀기 프로그램이 실패하는 것은 놀라운 일이 아닙니다.

아카이브의 끝에있는 디렉토리는 파일 메타 정보가 아카이브에 저장되는 유일한 위치 는 아닙니다 . 또한 개별 항목은 중복을 위해이 정보를 로컬 파일 헤더에 포함합니다.

모든 ZIP 압축 풀기 프로그램이 색인을 사용할 수 없을 때 로컬 파일 헤더를 사용하는 것은 아니지만 tar 및 cpio 프론트 엔드는 libarchive (일명 bsdtar 및 bsdcpio) 로 파이프를 읽을 때 수행 할 수 있으며 그렇게 할 입니다. 이는 다음을 가능하게합니다.

wget -qO- http://example.org/file.zip | bsdtar -xvf-

1
이것은 우수하다! tar는 압축되지 않은 데이터가 잘못된 크기 (예상 0 임)라는 경고를 표시하지만 파일 자체는 손상되지 않은 것으로 보입니다. 이것을 추측하는 것은 지수가 없기 때문입니다.
Wyatt8740

1
.zip실행 권한이있는 파일이 포함 된 -file이 있습니다. 다운로드하여 파이프에 넣으면 bsdtarexec 비트가 버려집니다. 디스크로 다운로드하여 추출 bsdtar하거나 unzipexec 비트를 추출 하면 exec 비트가 존중됩니다.
Golar Ramblar

//, @GolarRamblar, 왜 그런지 알아 낸 적이 있습니까?
Nathan Basanese

1
@NathanBasanese : 여기 에 답이 있습니다. 간단히 말해서 : ZIP 아카이브에는 이러한 정보를 저장하는 두 곳이 있으며, 이는 일관성이 없을 수 있으며 파일을 bsdtar열 수 있는지 여부에 따라 하나 또는 다른 곳을 사용합니다.
Golar Ramblar

20

JDK를 설치 한 경우 다음을 사용할 수 있습니다 jar.

wget -qO- http://example.org/file.zip | jar xvf /dev/stdin

3
방금 jar파일 권한을 유지하지 못한다는 것을 알았습니다 . 그렇지 않으면 좋은 트릭입니다.
phunehehe

7
파일 매개 변수를 제공 할 필요는 없습니다.| jar xv
cricket_007

15

wget의 출력을 압축 해제로 귀찮게하고 싶지 않다고 생각합니다.

Wikipedia "ZIP (파일 형식)" 기사에서 :

ZIP 파일은 파일의 끝에 위치한 중앙 디렉토리의 존재로 식별됩니다.

압축 해제는 작업을 수행하기 전에 wget이 다운로드를 완전히 완료해야하므로 생각대로 짜여지지 않고 순차적으로 실행됩니다.


10

올바른 구문은 다음과 같습니다.

$ unzip <(curl -sL https://www.winpcap.org/archive/1.0-docs.zip)

하지만 오류로 인해 (의 작동하지 않습니다 정보-ZIP데비안 ) :

lseek(3, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)

Archive:  /dev/fd/63
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of /dev/fd/63 or
        /dev/fd/63.zip, and cannot find /dev/fd/63.ZIP, period.

또는 BSD / OS X에서 :

Trying to read large file (> 2 GiB) without large file support

표준 zip 도구는 주로 중앙 디렉토리 레코드 의 끝을 읽도록 끝에 파일 오프셋을 설정하기 위해 lseek기능 을 사용하기 때문입니다 . 아카이브 구조의 끝에 있으며 파일 목록을 읽어야합니다 ( Zip 파일 형식 구조 참조 ). 따라서 입력 오브젝트를 함수 로 배치 할 수 없으므로 파일은 FIFO, 파이프, 터미널 장치 또는 기타 동적 파일 일 수 없습니다 .lseek

따라서 다음 해결 방법이 있습니다.

  • (예를 들어, 압축의 종류를 사용하여 tar.gz),
  • 두 개의 별도 명령을 사용해야합니다
  • 대체 도구를 사용하십시오 (다른 답변에서 제안한대로).
  • 여러 명령을 사용하기 위해 별명 또는 함수를 작성하십시오.

나는 그것이 여전히 FIFO 일 있다고 생각합니다 . EOF (메모리 또는 임시 파일의 전체 FIFO를 효과적으로 버퍼링)까지 FIFO에서 계속 읽어야합니다. 스크립트 작성을 쉽게 할 수는 있지만 유용하지는 않습니다.
Evan Carroll

8

내 대답다시 게시 :

BusyBox unzip는 stdin을 가지고 모든 파일을 추출 할 수 있습니다.

wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.zip | busybox unzip -

대시 unzip는 stdin을 입력으로 사용하는 것입니다.

당신은 할 수 있습니다

cat file.zip | busybox unzip -

그러나 그것은 단지 중복입니다 unzip file.zip.

배포판에서 기본적으로 BusyBox를 사용하는 경우 (예 : 알파인)을 실행하십시오 unzip -.


매우 유용한 트릭, 감사합니다!
Brice

-1

이것은 나를 위해 아주 잘 작동합니다 :

tar xvf <(curl -sL http://www.vim.org/scripts/download_script.php?src_id=11834)

jar xvf <(curl -sL http://www.vim.org/scripts/download_script.php?src_id=11834)

wget -qO- http://www.vim.org/scripts/download_script.php?src_id=11834 | tar xvf -

wget -qO- http://www.vim.org/scripts/download_script.php?src_id=11834 | jar xvf -
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.