Jak przekierować wyjście wget jako dane wejściowe do rozpakowania?

Muszę pobrać plik z tego linku . Pobrany plik jest plikiem zip, który będę musiał rozpakować w bieżącym folderze.

Zwykle najpierw pobrałbym go, a następnie wykonałem polecenie rozpakowania.

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

Ale w ten sposób muszę wykonać dwie komendy, poczekać na zakończenie pierwszej, aby wykonać następną, muszę też znać nazwę pliku temp.zip aby przekazać je do unzip.

Czy jest możliwe przekierowanie wyjścia wget do unzip? Coś w rodzaju

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

Ale to nie zadziałało.

bash: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip: niejednoznaczne przekierowanie

Ponadto wget został wykonany dwukrotnie , i pobrał plik dwukrotnie.

Komentarze

  • W tym drugim przykładzie wget został prawdopodobnie wykonany dwukrotnie, ponieważ? to znak specjalny w powłoce . Umieszczenie adresu URL w ” ” s powinno pomóc.
  • Ten wątek wydaje się mieć rozwiązanie. Przystań ' sam tego próbowałem. serverfault.com/questions/26474/…

Odpowiedź

Musisz pobrać pliki do pliku tymczasowego, ponieważ (cytując rozpakowany plik man):

Archiwa czytane ze standardowego wejścia nie są jeszcze obsługiwane, z wyjątkiem funzip (i wtedy tylko pierwsze m ember z archiwum można rozpakować).

Po prostu połącz ze sobą polecenia:

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

Ale aby uczynić go bardziej elastycznym, prawdopodobnie powinieneś umieścić go w skrypcie, aby zaoszczędzić trochę pisania i aby upewnić się, że nie nadpisujesz czegoś przypadkowo, możesz użyć mktemp, aby utworzyć bezpieczną nazwę pliku dla pliku tymczasowego:

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

Komentarze

  • Czy wget file.zip && unzip file.zip to samo co wget file.zip; unzip file.zip, czy też jest preferowane? Dzięki 🙂
  • @NextLocal wget && unzip uruchomi rozpakowywanie tylko wtedy, gdy wget się powiedzie. wget ; unzip i tak uruchomi rozpakowywanie, prawdopodobnie wskazując na nieistniejący plik.
  • funzip był odpowiedzią, której szukałem. Terraform (z jakiegoś powodu) pakuje go ' jako pojedynczy plik w archiwum zip, więc było to dla mnie idealne.

Odpowiedz

To jest ponowna publikacja mojej odpowiedzi na podobne pytanie:

Format pliku ZIP zawiera katalog (indeks) na końcu archiwum. Ten katalog mówi, gdzie w archiwum znajduje się każdy plik, co pozwala na szybki, losowy dostęp bez czytania całego archiwum.

Wydaje się, że stanowi to problem podczas próby odczytania archiwum ZIP za pomocą pipe, ponieważ indeks nie jest dostępny do samego końca, a więc poszczególne elementy nie mogą być poprawnie wyodrębnione, dopóki plik nie zostanie w całości odczytany i nie będzie już dostępny. W związku z tym nie wydaje się zaskakujące, że większość dekompresorów ZIP po prostu zawodzi, gdy archiwum jest dostarczane przez potok.

Katalog na końcu archiwum nie jest jedyną lokalizacją, w której plik meta informacje są przechowywane w archiwum. Ponadto poszczególne wpisy również zawierają te informacje w nagłówku pliku lokalnego, ze względu na nadmiarowość.

Chociaż nie każdy dekompresor ZIP będzie używał lokalnych nagłówków plików, gdy indeks jest niedostępny, fronty tar i cpio do libarchive (aka bsdtar i bsdcpio) mogą i będą robić to, gdy czytanie potoku, co oznacza, że możliwe są następujące rzeczy:

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

Komentarze

  • To świetnie ! Chciałbym zauważyć, że tar daje mi pewne ostrzeżenia, że nieskompresowane dane mają niewłaściwy rozmiar (oczekiwane 0), ale same pliki wydają się nieuszkodzone. Domyślam się, że jest to spowodowane brakiem indeksu.
  • Mam tutaj plik .zip, który zawiera pliki z uprawnieniami do wykonywania. Kiedy pobieram i przesyłam potokiem do bsdtar, bity exec są wyrzucane. Kiedy pobieram na dysk i rozpakowuję za pomocą bsdtar lub unzip, bity exec są honorowane.
  • // , @GolarRamblar, czy kiedykolwiek dowiedziałeś się, dlaczego?
  • @NathanBasanese: tutaj to odpowiedź. W skrócie: archiwum ZIP ma dwa miejsca, w których przechowuje takie informacje, które mogą być niespójne iw zależności od tego, czy plik bsdtar otwiera się, czy nie, używa jednego lub drugiego miejsca .

Odpowiedź

Jeśli masz zainstalowany pakiet JDK, możesz użyć jar:

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

Komentarze

  • Właśnie stwierdziłem, że jar nie ' t zachowuje uprawnienia do plików. W przeciwnym razie niezła sztuczka.
  • Nie ' nie musisz podawać parametru pliku, po prostu użyj | jar xv
  • Mnie też ugryzło założenie, że jar może zostać użyte jako zamiennik dla unzip; Niestety jar nie przywraca rozpakowanych plików ' uprawnień;
  • Po prostu użyj | jar x
  • jar znacznie lepiej obsługuje nazwy plików UTF-8. unzip zniekształcone rzeczy.

Odpowiedź

Nie myślisz, że chcesz nawet zawracać sobie głowę przesyłaniem danych wyjściowych wget do rozpakowania.

Z artykułu Wikipedii „ZIP (format pliku)” :

Plik ZIP jest identyfikowany na podstawie katalogu centralnego znajdującego się na końcu pliku.

wget musi całkowicie zakończyć pobieranie, zanim rozpakowanie będzie mogło wykonać jakąkolwiek pracę, więc działają sekwencyjnie, a nie są splecione, jak mogłoby się wydawać.

Odpowiedź

Ponownie opublikuj moja odpowiedź :

BusyBox „s unzip może pobrać standardowe wejście i wyodrębnić wszystkie pliki.

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

Myślnik po unzip oznacza wejście standardowe jako dane wejściowe.

Możesz nawet,

cat file.zip | busybox unzip - 

Ale to jest po prostu zbędne z unzip file.zip.

Jeśli twoja dystrybucja używa BusyBo x domyślnie (np. Alpine), po prostu uruchom unzip -.

Komentarze

  • dalej do @Saftever ' to odpowiedź, której ' nie mogę komentować, busybox będzie działał, ale wygra wersje starsze niż 1.27.0 ' t z powodu zbędnego lseek, patrz changelog busybox.net

Odpowiedź

Prawidłowa składnia byłaby następująca:

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

ale nie zadziała z powodu błędu ( Info-ZIP na Debian ):

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. 

lub na BSD / OS X:

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

Dzieje się tak, ponieważ standardowe narzędzia do zip używają głównie lseek funkcja , aby ustawić offset pliku na końcu, aby odczytać jego koniec rekordu katalogu centralnego . Znajduje się na końcu struktury archiwum i wymagane jest przeczytanie listy plików (patrz: Struktura formatu pliku Zip ). Dlatego plik nie może być FIFO, potokiem, urządzeniem końcowym ani żadnym innym dynamicznym, ponieważ obiekt wejściowy nie może być pozycjonowany przez funkcję lseek.

Więc masz następujące obejścia:

  • użyj innego rodzaju kompresji (np. tar.gz),
  • musisz użyć dwóch oddzielnych poleceń,
  • użyj alternatywnych narzędzi (jak sugerowano w innych odpowiedziach),
  • utwórz alias lub funkcję, aby używać wielu poleceń.

Komentarze

  • Myślę, że nadal może być FIFO. Musisz ' po prostu czytać z FIFO aż do EOF (efektywne buforowanie całego FIFO w pamięci lub w pliku tymczasowym). Całkowicie wykonalne, aby ułatwić tworzenie skryptów, ale niezbyt przydatne.

Odpowiedź

Jeśli jest tylko jeden plik w zip, możesz użyć zcat lub gunzip:

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

Do Twojej wiadomości: Oto definicje gunzip i zcat w moim systemie:

$ grep ^exec $(which gunzip zcat) /bin/gunzip:exec gzip -d "$@" /bin/zcat:exec gzip -cd "$@" 

Odpowiedź

zip archiwum nie jest sekwencyjne, ponieważ często zawiera spis treści na końcu pliku, więc trudno jest go rozpakować strumieniowo.

Alternatywnym rozwiązaniem jest sprawdzenie, czy możesz uzyskać inny format pliku, na przykład .tar.gz.

Na przykład, jeśli „pobierasz plik .zip z GitHub, prawie zawsze jest .tar.gz dostępna wersja.

Na przykład

Zwróć uwagę na wzorzec – po prostu zamień .zip na .tar.gz i potokuj do | tar xzf -

Odpowiedź

U mnie to działa całkiem nieźle:

 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 -  

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *