Czy istnieje metoda wiersza polecenia, za pomocą której mogę sprawdzić, czy pobrany plik jest kompletny czy uszkodzony?

13

Piszę skrypt, który wymaga pobrania i manipulowania plikiem, i chcę się upewnić, że plik nie jest niekompletny (z powodu np. Zerwanego połączenia) przed rozpoczęciem pracy.

Klara
źródło

Odpowiedzi:

10

Najczęstszym sposobem weryfikacji integralności pobranych plików jest użycie sum kontrolnych MD5. Zakłada się, że witryna, którą pobierasz z faktycznie opublikowanych sum kontrolnych MD5 ich plików. Możesz zweryfikować sumę kontrolną MD5, tworząc własną sumę kontrolną pobranego pliku i porównując ją z opublikowaną sumą kontrolną. Jeśli są identyczne, pobrany plik jest kompletny i nie jest modyfikowany.

Jeśli nie spodziewasz się, że plik, który pobierasz, zmieni się, możesz wstępnie obliczyć sumę kontrolną i zapisać go w skrypcie, ale jeśli plik zostanie kiedykolwiek zaktualizowany, weryfikacja zakończy się niepowodzeniem.

Aby utworzyć sumę kontrolną MD5 uruchomienia pliku md5sum myFile. W przypadku wget możesz uznać to polecenie za przydatne, szczególnie jeśli plik, który pobierasz, jest duży:

wget -O - http://example.com/myFile | tee myFile | md5sum > MD5SUM.

Spowoduje to utworzenie sumy kontrolnej „myFile” podczas pobierania i zapisanie jej w pliku MD5SUM, co może zaoszczędzić trochę czasu.

W przypadku zerwanego połączenia uważam, że najlepszym sposobem byłoby sprawdzenie kodów wyjściowych wget. Jeśli pobieranie powiedzie się bez żadnych błędów, wget powróci 0. Wszystko inne wskazuje, że coś poszło nie tak. Spójrz na sekcję „Status wyjścia” w man wget.

arnefm
źródło
2
kody wyjścia: gnu.org/software/wget/manual/html_node/…
mikeserv
7

Kod powrotu polecenia użytego do pobrania pliku powie ci, czy polecenie wykonało się pomyślnie, czy nie. Zazwyczaj kod powrotu 0 oznacza sukces, a każda niezerowa liczba oznacza błąd. Możesz uzyskać dostęp do kodu powrotu poprzez $?zmienną.

Podstawowym przykładem użycia wgetbyłoby:

#!/bin/bash

wget foo.tgz &> /dev/null

if [[ "$?" != 0 ]]; then
    echo "Error downloading file"
else
    echo "Success"
fi

&> /dev/nullprzekierowuje wszystkie dane wyjściowe wget do, /dev/nullwięc jest idealny do tworzenia skryptów, ALE utrudnia to debugowanie wgetbłędów.

zatoczka
źródło
4
możesz zamiast tego:wget -q ... || { handle ; error ; }
mikeserv
@mikeserv Nawet nie wiedziałem, że tam był, miły akcent
Creek
1
znalazłem to tylko manpodczas czytania odpowiedzi, a dwie rzeczy, które zamierzałem powiedzieć, były już w dwóch odpowiedziach - więc zrobiłem dwa komentarze. Miły akcent również dla ciebie.
mikeserv
Spodziewam się, że to nie zadziała, gdy zostanie użyte z serwerami proxy SOCKS, takimi jak tor.
CodesInChaos
1
@Creek Miałem na myśli to, że wgetmoże się wydawać, że pobieranie zostało ukończone, nawet jeśli się zepsuło. Informacje proxy o zerwanych połączeniach TCP vs. zamkniętych połączeniach TCP, co jest problematyczne z HTTP, ponieważ domyślnie używa zamkniętego TCP jako znacznika końcowego. Dlatego dodałem sprawdzenie, czy rozmiar pliku w nagłówku odpowiada rozmiarowi pobranego pliku, gdy uruchomiłem masowe pobieranie. Nie jestem pewien, czy wgetsprawdzana jest taka spójność lub co mówi specyfikacja http na ten temat.
CodesInChaos