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 cowget 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 dobsdtar
, bity exec są wyrzucane. Kiedy pobieram na dysk i rozpakowuję za pomocąbsdtar
lubunzip
, 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 dlaunzip
; Niestetyjar
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
- https://github.com/madler/zlib/archive/v1.2.11.zip
- https://github.com/madler/zlib/archive/v1.2.11.tar.gz
- https://github.com/curl/curl/archive/curl-7_68_0.zip
- https://github.com/curl/curl/archive/curl-7_68_0.tar.gz
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 -