Domyślnie polecenie cp, służące do kopiowania plików oraz katalogów nie posiada paska postępu swojej pracy. Od zawsze to była wielka wada polecenia. Ciężko było oszacować kiedy plik zostanie skopiowany, czy proces kopiowania nadal trwa. Na szczęście istnieją inne polecenia, które rozwiązały ten problem.

Zawsze można skorzystać z narzędzia pv, które służy do łączenia plików lub wejścia standardowego, do wyjścia standardowego z monitoringiem. Polecenie to posiada wiele ciekawych przełączników, które służą do wizualizacji postępu kopiowania. Najprościej jest wydać polecenie:
[bash]paszczak000@muszelka:~$ pv -p /media/tatsuke/debian.iso > /dev/null
[==============================================================> ] 42%[/bash]
Oczywiście istnieją też inne parametry dla polecenia np:
[bash]-t, –timer show elapsed time
-e, –eta show estimated time of arrival (completion)
-r, –rate show data transfer rate counter
-b, –bytes show number of bytes transferred[/bash]
Dzięki nim można dodać dodatkowe informacje do paska postępu jak np. szybkość transferu pliku, czas pozostały do ukończenia operacji lub czas jaki upłynął od początku procesu kopiowania.
[bash]paszczak000@muszelka:~$ pv -p -r -t -e /media/tatsuke/debian.iso > /dev/null
0:00:04 [22,1MB/s] [======================================> ] 33% ETA 0:00:08[/bash]
Kolejną próbą stworzenia jakiś informacji na temat postępu kopiowania było zaciągnięcie do pracy polecenia curl. Wystarczy napisać bardzo prosty skrypt, którego parametrami są plik wyjściowy oraz plik docelowy.

#!/bin/bash
curl "file://$1" -o "$2"[/bash]
Wynikiem działania polecenia jest tabelka z informacjami na temat procesu kopiowania.
[bash]paszczak000@muszelka:~$ ./curl.sh /media/tatsuke/debian.iso /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
31 367M 31 115M 0 0 21.6M 0 0:00:16 0:00:05 0:00:11 21.7M[/bash]
Na szczęście za pomocą Basha można narysować pasek postępu kopiowania pliku. Pierwszą metodą jaką znalazłem było wykorzystanie narzędzia strace oraz Awk w skrypcie:
[bash]#!/bin/sh
cp_p()
{
set -e
strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
| awk '{
count += $NF
if (count % 10 == 0) {
percent = count / total_size * 100
printf "%3d%% [", percent
for (i=0;i<=percent;i++) printf "=" printf ">"
for (i=percent;i<100;i++)
printf " "
printf "]\r"
}
}
END { print "" }' total_size=$(stat -c '%s' "${1}") count=0
}[/bash]
Skrypt potrafi kopiować tylko pojedyncze pliki. Czasami zatrzymuje się na 99% i nie działa poprawnie, dlatego należy go stosować z rozwagą. Wynikiem działania polecenia jest:
[bash]paszczak000@muszelka:~$ ./cp_p /mnt/raid/pub/iso/debian/debian-2.2r4potato-i386-netinst.iso /dev/null
76% [===========================================> ][/bash]
Więcej tego typu szalonych pomysłów można znaleźć na stronie linuxquestions.org

.

Linki

8 Komentarze

  1. Czy nie łatwiej jest użyć mc zamiast pisać skrypty używające strace do wyświetlania paska postępu?

    No tak, zapomniałem, że jak ktoś używa mc, to nie jest l33t, a gdy pisze skrypty wyświetlające pasek postępu, to jego l33t jest inkrementowane wprost proporcjonalnie do długości… paska postępu.

  2. Why not ;-) To raczej był przykład, że się da coś zrobić. Pasek postępu pracy przydał mi się w poprzedniej firmie, gdzie za pomocą cp kopiowaliśmy różne pliki pasujące do pewnego wyrażenia regularnego. Nie umiem tego zrobić za pomocą mc. No i tutaj się udało i widziałem postęp prac ;-)

  3. To, ze cp nie ma pasku progressu to raczej jego zaleta. Zgodna z filozofia unixa – polecenie nie wypisuje niepotrzebnych smieci jezeli nie ma bledu.

    Ciche cp jest idealne do zastosowania w skryptach. Wyobraz sobie jakby to wygladalo, jakby kazde najmniejsze nawet cp plulo taka iloscia smieci…

    Jak juz ktos musi miec pasek progressu to pozostaje zawsze:

    rsync –progress source destination

  4. @vampire

    Jak już przedpiśca wspomniał, taka opcja byłaby bardzo fajna. (Zwróć uwagę, że napisałem opcja a nie zachowanie domyślne)

    "Zgodna z filozofia unixa – polecenie nie wypisuje niepotrzebnych smieci jezeli nie ma bledu."

    To mi strasznie przypomina linuksiarskie "w tym programie nie ma takiej opcji, bo tak naprawdę jej nie potrzebujesz"…

Odpowiedz