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:

paszczak000@muszelka:~$ pv -p /media/tatsuke/debian.iso > /dev/null 
[==============================================================>                                                                                       ] 42%

Oczywiście istnieją też inne parametry dla polecenia np:

-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

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.

paszczak000@muszelka:~$ pv -p -r -t -e /media/tatsuke/debian.iso > /dev/null 
0:00:04 [22,1MB/s] [======================================>                                                                                ] 33% ETA 0:00:08

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.
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

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:

#!/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
}

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:

paszczak000@muszelka:~$ ./cp_p /mnt/raid/pub/iso/debian/debian-2.2r4potato-i386-netinst.iso /dev/null
 76% [===========================================>                    ]

Więcej tego typu szalonych pomysłów można znaleźć na stronie linuxquestions.org

.

Linki

  • bongo

    dzięki, dodałem se do zakładek

  • Michał

    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.

  • Oczywiście, że łatwiej, ale nie o to chodzi w Bashowisku przecież ;-)

  • Michał

    Możesz jeszcze dodać do skryptu obsługę dialog, wtedy będzie super eye candy ;)

  • 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 ;-)

  • vampire

    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

  • Dlatego są opcje -v ew. -p (od progress), której tutaj brakło, a -v mało robi :]

  • Michał

    @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"…