ATTENZIONE: le procedure descritte qua sotto potrebbero portare alla perdita di dati. Eseguitele a vostro rischio e pericolo, non mi assumo responsabilità. Inoltre probabilmente ci sono vie più semplici per raggiungere lo stesso scopo, ma non le conosco. Se voi le conoscete, suggeritemi pure!Problema: portarsi sempre in giro su una chiavetta USB una serie di cartelle presenti sull’hard disk e mantenerle sempre aggiornate.
Soluzione: rsync e AppleScript

Cos’è rsync? in parole poverissime e terra terra è un tool UNIX per sincronizzare file e cartelle, posti anche su volumi remoti e così via. È potentissimo e le possibilità che offre sono esagerate. Su wikipedia una descrizione più accurata. Rsync è già integrato in OS X e non c’è bisogno di installare nulla! Per vedere una guida veloce di rsync aprite il terminale e digitate:

info rsync

diciamo che la sintassi base è rsync -attributi percorso_sorgente percorso_destinazione
quello che è importante ricordare è: mettere lo “slash” alla fine del percorso della cartella. Se ad esempio vogliamo copiare tutti i file della “Cartella1” nella “Cartella2” dovremo scrivere

rsync -attributi /percorso2/Cartella1/ /percorso2/Cartella2/

altrimenti il programma copierà la “Cartella1” come sottocartella di “Cartella2”.
Le altre cose che vorremmo poter fare sono:

  • rendere ricorsivo il processo, ovvero eseguirlo per tutte le sottocartelle: per questo serve l’attributo -r
  • non modificare i file che sono più aggiornati: in questo caso si deve usare l’attributo -u
  • copiare anche tutti gli attributi estesi, come ad esempio le immagini delle icone e così via: serve l’attributo -E (mi raccomando: E maiuscolo. Su Linux mi sembra che in questo caso si debba usare -X e -E serve ad altro, ma non sono sicuro)
  • infine si potrebbe scegliere di cancellare i file presenti nella cartella destinazione che non sono presenti in quella sorgente: basta usare l’attributo --delete

Ok, ora abbiamo che abbiamo un po’ di basi, definiamo la modalità con cui deve avvenire la sincronizzazione.
Io ho scelto due strategie:

  1. Unisci: copia nella cartella di destinazione i file più aggiornati, e viceversa. Si ottengono quindi due cartelle identiche, date dall’unione dei file più aggiornati, quindi senza dover cancellare nulla.
  2. Sync unidirezionale: la cartella destinazione viene modificata per risultare identica a quella sorgente. Vengono quindi eliminati gli eventuali file presenti nella destinazione e non nella sorgente. Si tratta, più o meno, di una intersezione tra cartelle.

Per la prima strategia ho concatenato due volte il comando rsync, con percorsi scambiati e, ovviamente, senza usare l’attributo delete. Forse c’è un modo più semplice ed elegante per farlo: se qualcuno lo sa, mi faccia sapere.
Per la seconda, invece, basta usare rsync una volta sola con l’attributo delete per cancellare i file in più.

Definite le varie possibilità, ho deciso di confezionare un bell’AppleScript che metta tutto insieme. Sono partito da questo, ottimo, presente sul forum di Tevac e l’ho modificato secondo le mie esigenze (ovvero specificando le cartelle di sorgente e destinazione) e le strategie scelte. Ecco il risultato:

(choose folder with prompt “Scegli la cartella sorgente”)
(choose folder with prompt “Scegli la cartella di destinazione”)
setsrcto“/Users/Jeby/Documents/Politecnico/AA_200708/II_Semestre/”
setdestto“/Volumes/JEBY2GB/AA_200708/II_Semestre/”

setsceltato(display dialog((“Unisci: rende le cartelle identiche, copiando i file di una nell’altra e viceversa;”&return&return&“Sync: rende la cartella”&return&(destasstring)&return&“identica a”&return&(srcasstring)&return&“eventualmente cancellando i file in più”))buttons{“Annulla”,“Unisci”,“Sync”}default button1with icon1with title“Poli2Jeby and back”giving up after15)
ifthebutton returnedofsceltais notequal to“Annulla”then
    ifthebutton returnedofsceltaisequal to“Unisci”then
        setcmdto(“/usr/bin/rsync -ruE “&(quoted formof(POSIX pathofsrc))&” “&(quoted formof(POSIX pathofdest))&“; /usr/bin/rsync -ruE “&(quoted formof(POSIX pathofdest))&” “&(quoted formof(POSIX pathofsrc)))
    else
        setcmdto(“/usr/bin/rsync -ruE –delete “&(quoted formof(POSIX pathofsrc))&” “&(quoted formof(POSIX pathofdest)))
    endif

try
        setrisultatoto(do shell scriptcmd)
setrisultatoto(risultato&“completata con successo.”)
    onerrore
        setrisultatotoe
    endtry
display dialog(“Esito:”&return&(risultatoasstring))buttons{“OK”}default button1with icon1with title“Poli2Jeby and back”giving up after5
endif

Le prime due righe di codice commentato mostrano i comandi per ottenere una finestra di dialogo con cui scegliere le cartelle volta per volta.
Per inserire il percorso delle cartelle “a mano”, come ho fatto io, basta trascinare dentro la finestra di Applescript le cartelle in questione. Mi raccomando, non dimenticate lo slash finale!
A questo punto l’AppleScript è fatto, lo testo dopo aver fatto un backup della cartella originale, e quindi lo salvo.
Ora nasce la necessità di automatizzare il processo, ovvero far partire lo script ogni qual volta viene inserita la chiavetta USB in questione. Dopo un tentativo fallito con Azioni Cartella (che non so usare, evidentemente), ho trovato il software che fa per me: Do Something When. Fantastico! È un pannello preferenze che consente di specificare il lancio di un file (applicazione, script, qualsiasi cosa) quando viene montato o smontato un volume. È utilissimo, benché forse ancora imperfetto: mi piacerebbe sapere se c’è un modo per far la stessa cosa senza ricorrere a questo programma, in attesa lo uso con soddisfazione. In alternativa si potrebbe usare il demone cron per specificare l’orario in cui far partire l’AppleScript, o più semplicemente iCal (meno sbatti).
Comunque ecco spiegati i giving up presenti nell’AppleScript: non è detto che ogni volta che infilo la chiavetta voglio sincronizzare qualcosa, mi basta farlo una volta al giorno. Così, se non è necessario, l’AppleScript annulla l’operazione dopo un tempo fissato.
Ok, ora è tutto pronto e, senza spendere un centesimo, abbiamo tutto ciò che ci serve per mantenere aggiornate le cartelle sul drive USB e quelle sull’hard disk. Il giochino può essere facilmente esteso a più cartelle, concatenando ad esempio i comandi rsync con un punto e virgola , così:

rsync -attributi cartella1 cartella2; rsync -attributi2 cartella5 cartella 7; ecc…

forse non è il modo più efficiente per farlo, ma io conosco solo questo (si attendono suggerimenti dai guru del terminale).

’nuff said