Progress bar pre rsync (Tcl/Tk, Emacs,…)

26.04 | 09:38 | Richard | Richard

Pri kopírovaní/synchronizovaní súborov a adresárov pomocou rsync máme dostupné informácie v konzole. Ako z nich spraviť „progress bar“ a ako ho použiť napr. v dired/pre Emacs?

 

Motivácia + slabina dired

Pôvodný zámer ísť na bicykel zhatilo počasie – veľkolepý lejak a následné blato. Pracovať sa mi už (a znovu) nechcelo, tak som sa rozhodol precvičiť sa v menej používanom jazyku Tcl (s Tk) a Elisp. Nakoniec to bolo také rýchle a stručné, že precvičovať nebolo veľmi čo 😀.

Užívatelia GNU Emacsu používajúci súborový manažér dired, alebo jeho deriváty ako diredc či Sunrise Commander často narazia na nepríjemnú vec ak kopírujú veľké súbory najmä na pomalé média, ako je USB kľúč. Vstavaná funkcia pre kopírovanie dired-do-copy si uzurupje čas pre seba a Emacs je v tomto momente nerenspozívny. Funkcia dired-async-do-copy dokáže pracovať na pozadí, ale zase jeden nemá poriadny prehľad, koľko sa toho skopírovalo.

Preto na kopírovanie v týchto prípadoch používam rsync. Ten je vhodný samozrejme i v bash-i, lebo ani tam klasický cp neposkytuje dostatočné informácie (preto je šikovný i program gcp).

Interaktívnu funkciu pre rsync mám v Emacse roky, ktorá v druhom buffri zobrazuje jeho postup, ale teraz som sa rozhodol pridať i tzv. progress bar, t.j. grafické znázornenie priebehu. Najprv som to chcel spraviť cez (inak) šikovný YAD, ale tam už bežiaci program nevie prijať informácie o takomto vstupe. Resp. nepodarilo sa mi to nájsť a ani AI nemala žiaden fungujúci návod. Zato sebavedomých nezmyslov niekoľko 🙄.

Tak som sa rozhodol pre použitie grafického frameworku Tk pre mocný skriptovací jazyk Tcl.

Výsledok je taký:

Obr. 0: „Progress bar“ v akcii

Ako takútu „nádheru“ dosiahnuť?

Možno nemotorne, ale prostredníctvom troch skriptov.

Princípom je počítanie, koľko súborov musí rsync prekopírovať alebo zosynchronizovať a potom pri tejto činnosti počítať percento priebehu a to zobrazovať.

Samotné skripty sú na mojom gitlabe.

copy-scipt.sh

Tento bash skript zistí počet súborov a následne ich začne kopírovať. Áno, áno, nevie, aká bude celková veľkosť prenesených dát. Túto informáciu rsync neposkytuje. Takže 50% v progress bar-e znamená, že bola prekopírovaná polovica súborov. Ale myslím, že pre bežné použitie je to dobrá informácia a tiež aj informácia o tom, „že niečo sa deje“.

rsync-progress.sh

Toto je hlavný skript, ktorý interaguje s užívateľom. Takže namiesto klasického:

cp <súbor, adresár, alebo viac súborov či adresárov> <destinácia>

použijeme

rsync-progress.sh <súbor, adresár, alebo viac súborov či adresárov> <destinácia>

Alebo si na to niekto môže spraviť alias apod.

Pred prvým použitím je ale potrebné editovať riadok č. 3, v ktorom je definované, kde sa pomocné skripty nachádzajú, napríklad:

path_to_scripts="/home/richard/bin/tcl-rsync-progressbar/" (pozor na konci musí byť /).

A teda tento program nielenže začne kopírovanie, ale do Tcl/Tk programu tcl-progressbar.sh posiela informácie o priebehu.

tcl-progressbar.tcl

Tento program číta štandardný vstup, na ktorom je číslo, percento z programu rsync-progress.sh, a to zobrazuje. Nič viac.

V programe možno ešte nastaviť veľkosť progress bar-u a prípadne umiestnenie okna, ak sa nám nepáči, kde nám to ukladá náš okenný manažér.

ešte funkcia do Emacsu

Táto funkcia:

(defun sr-rsync-copy-with-progressbar (dest)
  "Copy files using rsync with Tcl/Tk progressbar."
  (interactive
    (list
      (expand-file-name (read-file-name "rsync to: "
                          (dired-dwim-target-directory)))))
  (let ((files (dired-get-marked-files nil current-prefix-arg))
        (command "/home/richard/bin/tcl-rsync-progressbar/rsync-progress.sh "))
    (dolist (file files)
      (setq command (concat command (shell-quote-argument file) " ")))
    (setq command (concat command (shell-quote-argument dest)))
    (async-shell-command command "*rsync*")
    (dired-unmark-all-marks)
    (other-window 1)
    (sleep-for 1)
    (dired-revert)
    (revert-buffer nil t nil))
  (message "* rsync done *")
  (let ((buffer-name "*rsync*"))
    (if (get-buffer buffer-name)
        (when (yes-or-no-p (format "Do you want to close the buffer %s? " buffer-name))
          (kill-buffer buffer-name))
      (message "Buffer %s does not exist." buffer-name)))) 

nám zjednoduší používanie v Emacse. Kopíruje takto označené súbory a adresáre v dired a jeho derivátoch, pričom nám ponúka i destináciu. Ako veľmi interaktívne, to závisí od použitého „completition“ frameworku toho-ktorého užívateľa (napr. fido, helm…).

Na nasledujúcich obrázkoch (lebo tých je tu zatiaľ málo) označím adresár i súbor a zavolám funkciu sr-rsync-copy-with-progressbar (hehe, to uvodzujúce „sr“ je tam preto, lebo som kedysi používal Sunrise Commander a takto som si označoval funkcie pre neho, hoci ho už teraz nepoužívam 😀).

Okno s progress bar-om nie je modálne, takže ho človek môže presunúť inam, na inú plochu a pod.

Obr. 1 – 3: Kopírovanie v diredc
Obr. 4: Kopírovanie z príkaz. riadku v konzole

Zrada rsync-u a slabé stránky programu

Pri spúštaní programu rsync-progress.sh a rsync z príkazového riadku vo všeobecnosti je potrebné dávať pozor na / v cestách.

Len na ilustráciu:

Ale

Slabou stránkou programu ešte je, že načítava v programe rsync-progress.sh všetky argumenty okrem posledného ako zdrojové súbory/adresáre, a posledný argument je destinácia. Ak majú zdrojové súbory v názve medzery, chudák program si myslí, že to je už iný súbor/adresár a blbne. Takže zatiaľ nás stroje ešte neovládli! 😀

Navrhované riešenia ako --itemize-changes a pod. neviedli k úspechu. No ale aspoň mám nejakú úlohu do budúcnosti.

Alebo niekto príde s vylepšením.

Záver

Ako spieva Frank Sinatra v „My Way“: „I did it my way“. A just a to je perfektné! Či nie?

    • RE: Progress bar pre rsync (Tcl/Tk, Emacs,…) 26.04 | 22:48
      Avatar redhawk1975 Windows 11 nonsystemd edition  Používateľ

      pekna praca.

      Len ked ja nemam rad emacs a vim :D

      Na bike sa chystam. budem off webu asi 3 tyzdne  caka ma dlllhaaaa cesta. v pondelok som dal 160km za 8,5h.

      Do or do not. There is to no try.​ Když pohřbíš moc tajemství, na hřbitově dojde místo.
      • RE: Progress bar pre rsync (Tcl/Tk, Emacs,…) Včera | 01:59
        Avatar Pavel Q4OS, DistroWatch  Administrátor

        A skadiaľ budeš mať trasu? Nech ti zakývame a podáme vodu :-)

        • RE: Progress bar pre rsync (Tcl/Tk, Emacs,…) Včera | 10:01
          Avatar redhawk1975 Windows 11 nonsystemd edition  Používateľ

          kusok len :-)

          denne cca 150km ale mozno aj viac.

          Do or do not. There is to no try.​ Když pohřbíš moc tajemství, na hřbitově dojde místo.
    • RE: Progress bar pre rsync (Tcl/Tk, Emacs,…) Dnes | 08:06
      Avatar uid0 Debian  Používateľ

      rozmyslal som ako to je spravene, zaujimave riesenie s tym dry-run... asi moze existovat pripad, ze sa to bude lisit oproti skutocnosti

      Debian. apt-get into it…