ANNIDARE COMANDI MULTIPLI IN UN CICLO FOR

Ma anche: Backup di PostgreSql in Windows

Il caso del backup di un database PostgreSql mi permette di trattare un argomento su cui lavoro da molto tempo: lo scripting per Windows.

Il sistema più rapido di scrivere script per il sistema operativo di casa Microsoft, ma anche quello più datato e diffuso, è usare i file batch. Supposto che sei a conoscenza delle basi di questo linguaggio storico, vorrei suggerirti un sistema molto elegante di "annidare" diversi comandi in una sola riga, quando tratti un ciclo for.

La mia esigenza è nata dal dover cancellare la directory più vecchia, in una lista di directory; ogni giorno, la procedura crea una cartella su cui direziona il backup di un database Postgresql. Ad ogni esecuzione del batch, la cartella più vecchia viene cancellata.
Il codice è il seguente:

:INIZIO
@echo off
// REM Leggere la data di sistema (se italiano) e prenderne anno_mese_giorno
for /F "tokens=1-3 delims=/ " %%i in ('date /t') do set datestr=%%k-%%j-%%i
// REM Concatenare a questa variabile l'ora attuale (sempre con sistema localizzato italiano)
for /F "tokens=1-2 delims=:" %%i in ('time /T') do set datetimestr=%datestr%_%%i-%%j
// REM Dichiarare le variabili: cartella radice dei backup, nome del file di backup e password PostgreSql
set BKP_DIR=X:\BACKUP_PG
set BKP_FILE=%BKP_DIR%\pg_%datetimestr%.backup
SET PGPASSWORD=financial
:BACKUP_PG
// REM scriviamo qualcosa per l'utente...
echo Questo e' il nome del file di backup: %BKP_FILE%
echo on

// REM Lanciamo la procedura di backup del DB
"C:\Program Files\PostgreSQL\9.1\bin\pg_dump" -i -h localhost -p 5678 -U financial -F d -b -v -f %BKP_FILE% financial
echo.
echo.
@echo off
:OLDDEL
// REM Finalmente cancelliamo la cartella più vecchia
for /F %%i IN ('DIR /AD /OD /B %BKP_DIR%') DO (
rd /S /Q %BKP_DIR%\%%i
exit
)

Soffermandoci sulle ultime istruzioni, il comando for cicla sul risultato di un comando DIR in cui sono elencate solo le directory (pertanto eventuali file nella cartella principali non saranno toccati) ordinate per data, dalla più vecchia alla più recente.
Successivamente sottopongo due comandi, chiudendoli tra parentesi: il primo cancella la prima cartella della lista; il secondo esce, evitando di cancellare anche le altre.

Insomma, il segreto per annidare diversi comandi nello stesso ciclo for sta tutto in quelle parentesi e nel dichiarare ogni comando su una riga a sé stante. Seguendo questa sintassi, gli scenari che si aprono sono molteplici. In primis, la possibilità di racchiudere un For all'interno di un ciclo For; ma anche quella di innestare una funzione If o qualsiasi altra serie di comandi.
Certo su Linux sarebbe sufficiente una pipe, ma in fondo anche in Windows c'è da divertirsi. :-)