← Alle AI Script Backup · bash

backuptousb

Pakker mapper rett ned på en ekstern disk som ett komprimert arkiv per mappe. Skrevet fordi kopiering av mange små filer til USB er tregt på en måte som ikke gir mening før du vet hvorfor.

Fri bruk Linux + bash tar + zstd Ingen installasjon

Problemet det løser

Dra en mappe med 50 000 småfiler over på en minnepenn, og du får 2 MB/s på en disk som fint klarer 100. Det er ikke disken som er treg. Hver eneste fil betyr en runde med åpne, skrive, lukke, og det er de rundene du venter på, ikke selve dataene.

Ett arkiv er én sammenhengende strøm av byte. Da får du full diskhastighet. Det er hele trikset, og tar har kunnet det i førti år - dette scriptet pakker det bare inn i noe du orker å bruke daglig, med framdrift, sikringer og fornuftige standardvalg.

Kom i gang

Last ned fila, gjør den kjørbar, og legg gjerne inn et alias så den er tilgjengelig overalt:

bash
$ chmod +x ~/scripts/backuptousb
$ echo "alias backuptousb='~/scripts/backuptousb'" >> ~/.bashrc
$ source ~/.bashrc

Åpne så fila og sett standard-målmappa øverst, i EDIT ME-blokka. Det er den eneste innstillingen de fleste trenger å røre:

backuptousb - EDIT ME
DEFAULT_DEST="/media/youruser/usbdiskname/backups"   # hvor arkivene havner
COMPRESSION="zstd"                        # zstd | gzip | none
ZSTD_LEVEL="3"                           # 1-19; 3 er raskt og bra
DATESTAMP="no"                            # yes -> claude-20260716.tar.zst

Bruk

Kjør den fra mappa over det du vil pakke. Scriptet krever relative stier nettopp derfor: da inneholder arkivet myproject/…, og du kan pakke det ut hvor som helst uten å dra med deg /home/deg/ inn i arkivet.

backuptousb mappe/Pakker én mappe. Trykk Enter for å godta forslaget til filnavn.
backuptousb a/ b/ c/Ett arkiv per mappe. Du blir spurt om målmappa én gang, så går resten uten avbrudd.
backuptousb notes.txtEnkeltfiler går like fint som mapper.
-yIngen spørsmål. Bruker standardmappa. For cron og script.
-o <sti>Overstyrer navn og plassering for ett enkelt arkiv.
-hSkriver ut hele kommentarblokka fra toppen av fila.

En vanlig kjøring

Her pakkes en prosjektmappe og en løs fil i samme slengen. Legg merke til at node_modules aldri telles med - mappa inneholdt 53 filer, scriptet pakker 55 oppføringer (filer pluss kataloger) og hopper over resten:

backuptousb myproject/ notes.txt
$ cd ~
$ backuptousb myproject/ notes.txt

2 sources to back up:
  myproject/  ->  myproject.tar.zst
  notes.txt  ->  notes.txt.tar.zst

Destination folder (Enter to accept): /media/youruser/usbdiskname/backups

[1/2] myproject/

Packing  myproject/
     ->  /media/youruser/usbdiskname/backups/myproject.tar.zst

Sizing... 55 files, 220K

[#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#] 100%  00:00 taken

Flushing to disk... done

  Source    220K  (55 files)
  Archive   689  ->  /media/youruser/usbdiskname/backups/myproject.tar.zst
  Shrunk to 0.3% of original
  Time      0m 0s
  Speed     (too fast to measure)

[2/2] notes.txt

Packing  notes.txt
     ->  /media/youruser/usbdiskname/backups/notes.txt.tar.zst

Sizing... 1 files, 4.0K

[#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#][#] 100%  00:00 taken

Flushing to disk... done

  Source    4.0K  (1 files)
  Archive   102  ->  /media/youruser/usbdiskname/backups/notes.txt.tar.zst
  Shrunk to 2.4% of original
  Time      0m 0s
  Speed     (too fast to measure)

========================================
  2 of 2 sources packed
  224K  ->  791  in  0m 0s
========================================

Scripts on the backup disk:
  + /media/youruser/usbdiskname/backups/backuptousb
  + /media/youruser/usbdiskname/backups/extracttodisk

To restore:  /media/youruser/usbdiskname/backups/extracttodisk <archive.tar.zst>

På ekte data ser tallene selvsagt annerledes ut - en 60 GB mappe bruker minutter, ikke sekunder, og da er det ETA-en i framdriftslinja du følger med på. Poenget med utskriften er at du får se hva som faktisk skjedde: hvor mye som ble lest, hvor stort arkivet ble, og hvor det ligger.

Når arkivet finnes fra før

Kjører du på nytt over et arkiv som allerede finnes, får du tallene for begge før du bestemmer deg. Ikke bare «filen finnes, overskrive?», men hvor gammelt det gamle arkivet er og hvor stor kilden er nå:

overskriving
myproject.tar.zst already exists:
  existing archive       689   packed 2026-08-05 12:15
  myproject/ source now  220K   (55 files, uncompressed)

Overwrite? [y/N] _

Sikringene

En avbrutt kjøring ødelegger ikke det du hadde

tar skriver normalt rett i målfila. Blir kjøringen drept halvveis, sitter du igjen med en avkortet fil under det riktige navnet - en backup som ser ut som en backup, men ikke er det. Dette scriptet pakker alltid til arkiv.tar.zst.partial først, og gir den det endelige navnet bare etter at tar har avsluttet rent. Ctrl-C, strømbrudd eller full disk gjør at den halve fila ryddes bort og det forrige, hele arkivet blir stående urørt.

Én uleselig fil stopper ikke en 60 GB backup

Dette er ikke teori. En rot-eid fil midt i treet fikk en 60 GB kjøring til å avbryte på 55 GB. Nå kjører tar med --ignore-failed-read: uleselige filer blir hoppet over, telt opp på skjermen, og listet i en .skipped.log ved siden av arkivet. Kjøringen fullfører, og du får vite nøyaktig hva som manglet.

Framdrift som stemmer

Framdriftslinja teller filer, ikke byte. Byte-basert framdrift blir grovt feil på trær med mange små filer, fordi hver fil rundes opp til en tar-blokk på 512 byte - målt på et tre med 20 000 småfiler hoppet en byte-basert linje fra 38 % rett til 100 %. Filtelling er eksakt uansett filstørrelse.

Databasemapper hoppes over med vilje. db-data og mysql-data står i ekskluderingslista. En levende InnoDB-mappe kopiert under en kjørende server er et revet øyeblikksbilde som fort ikke lar seg gjenopprette i det hele tatt. Ta heller en mariadb-dump ned i prosjektmappa, så blir dumpen med i arkivet som en helt vanlig fil.

Hva som ikke er med

Det finnes ingen inkrementell logikk. Hver kjøring leser hele kilden på nytt. Skal du ha «bare det som er endret», er rsync riktig verktøy ved siden av dette, ikke tar.

Scriptet skriver rett til USB. Ryker kabelen midt i, har du en avkortet fil og ingen lokal kopi. For noe virkelig kritisk: pakk til lokal disk først, og kopier den ene ferdige fila over etterpå.

Den rå kommandoen bak

Vil du heller skrive det selv, er det dette scriptet i praksis gjør:

tar
# pakk
$ tar -I 'zstd -3 -T0' -cf /media/youruser/usbdiskname/backups/myproject.tar.zst myproject/

# pakk ut
$ tar -I zstd -xf myproject.tar.zst

# se innholdet uten å pakke ut
$ tar -I zstd -tf myproject.tar.zst | less

Vedlikeholdes ikke - endre den selv

Dette scriptet er laget for min egen maskin og legges ut som det er. Det blir ikke oppdatert, og jeg tar ikke imot feilmeldinger eller ønsker.

Trenger du at det gjør noe annet, gi hele fila til Claude, ChatGPT eller en annen AI og be om endringen med vanlige ord: «legg dato i filnavnet», «bruk gzip i stedet for zstd», «skriv til to disker etter hverandre», «send meg e-post når den er ferdig». Fila er tett kommentert nettopp for at en AI skal kunne lese den og skjønne hvorfor koden er som den er - det var sånn den ble til.