mercoledì 20 maggio 2015

Script MS DOS ... prendiamoci una pausa

Sono anni che bazzico lo scripting per risolvere ed automatizzare problemi che incontro nel mio lavoro quotidiano.
Spesso, all'interno di essi, ho bisogno di inserire delle pause di qualche secondo per permettere al computer in uso di effettuare delle operazioni che avvengono in background.
Quando devo scrivere questi script in ambiente Windows/MS-DOS ricordo sempre che non esiste un comando di sleep come in altri sistemi. Io da anni ho trovato la mia soluzione, ma sempre più spesso in sistemi gestiti anche da altri noto la presenza di sleep.exe
Tendenzialmente sono contrario ad installare tutto ciò che non è necessario su un sistema, ancora di più quando si tratta di un server.
Io ho due soluzioni a questo problema.

PING: Per risolvere il mio problema da anni utilizzo il comando ping.
Ma come il ping si utilizza, in genere, per testarsi un sistema remoto
mi si dice, ma io rispondo che
esso si può utilizzare anche per questo motivo
Eseguendo dal prompt del dos il comando ping /? si apre il suo help e possiamo trovare le seguenti informazioni:
Sintassi: ping [-t] [-a] [-n conteggio] [-l dimensioni] [-f] [-i TTL]
               [-v tipo-servizio] [-r conteggio] [-s conteggio]
               [[-j elenco-host] | [-k elenco-host]] [-w timeout]
               [-R] [-S indirizzo-origine] [-4] [-6] nome_destinazione

Opzioni:
    -t                    Esegue il ping dell'host specificato finché non
                          viene interrotto. Per visualizzare le statistiche
                          e continuare, premere CTRL+INTERR.
                          Per interrompere, premere CTRL+C.
    -a                    Risolve gli indirizzi in nomi host.
    -n conteggio          Numero di richieste echo da inviare.
    -l dimensioni         Dimensioni del buffer di invio.
    -f                    Imposta il contrassegno per la disattivazione della
                          frammentazione nel pacchetto (solo IPv4).
    -i TTL                Durata (TTL).
    -v tipo-servizio      TOS (tipo di servizio) (solo IPv4 - questa impostazione
                          è obsoleta e non produce alcun effetto sul campo del
                          tipo di servizio nell'intestazione IP).
    -r conteggio          Registra la route per il conteggio degli hop (solo IPv4).
    -s conteggio          Timestamp per il conteggio degli hop (solo IPv4).
    -j elenco-host        Routing libero lungo l'elenco host (solo IPv4).
    -k elenco-host        Routing vincolato lungo l'elenco host (solo IPv4).
    -w timeout            Timeout in millisecondi per l'attesa di ogni risposta.
    -R                    Usa l'intestazione di routing anche per il test del
                          routing inverso (solo IPv6).
    -S indirizzo-origine  Indirizzo di origine da utilizzare.
    -4                    Impone l'utilizzo di IPv4.
    -6                    Impone l'utilizzo di IPv6.
Le informazioni interessanti, nel caso specifico, sono:
  • il comando ping invia un pacchetto al secondo; 
  • possiamo  decidere quanti pacchetti inviare (opzione -n );
  • possiamo effettuare il ping su noi stessi (127.0.0.1 localhost);
  • possiamo evitare di vedere l'output del comando (>nul), può risultare dannoso all'interno di un log.
Nel mio caso ho creato un file chiamato sleep.bat contenente i seguenti comandi:
REM Faccio 30 secondi di pausa
echo %time%
ping -n 30 127.0.0.1 >nul
echo %time%
Lo ho eseguito ed ecco  l'output:
C:\Users\mprocida01\Documents\Butta>sleep.bat
C:\Users\mprocida01\Documents\Butta>REM Faccio 30 secondi di pausa
C:\Users\mprocida01\Documents\Butta>echo 16:31:21,28
16:31:21,28
C:\Users\mprocida01\Documents\Butta>ping -n 30 127.0.0.1  1>nul
C:\Users\mprocida01\Documents\Butta>echo 16:31:51,13
16:31:51,13
Variando il valore dell'opzione -n si può ottenere la pausa del valore in secondi voluto, in alcuni casi ho utilizzato il valore 600 (10 minuti) per esser sicuro di aver terminato l'operazione precedente.

TIMEOUT: Dai tempi di Windows Vista Microsoft ha introdotto un nuovo comando, ho impiegato molto tempo a trovarlo, per via del nome anomalo.
Eseguendo il solito comando di help (Timeout /h) dal prompt del DOS ecco cosa ci appare:
C:\Users\mprocida01\Documents\Butta>timeout /?
TIMEOUT [/T] timeout [/NOBREAK]
Descrizione:
    Questa utilità accetta un parametro timeout e consente di
    attendere per il periodo di tempo specificato (in secondi)
    o finché non viene premuto un tasto. Accetta inoltre un
    parametro che consente di ignorare la pressione dei tasti.
Elenco parametri:
    /T        timeout       Specifica il numero di secondi
                            che è necessario attendere.
                            L'intervallo valido è compreso tra
                            -1 e 99999 secondi.
    /NOBREAK                Ignora le pressioni dei tasti e attende
                            il periodo di tempo specificato.
    /?                      Visualizza questo messaggio della Guida.

NOTA: il valore -1 per il parametro timeout indica un tempo di
attesa indefinito (finché non viene premuto un tasto).

Esempi:
    TIMEOUT /?
    TIMEOUT /T 10
    TIMEOUT /T 300 /NOBREAK
    TIMEOUT /T -1
L'uso di tale comando è più agevole del precedente, forse, ma i risultati sono esattamente gli stessi, trvo interessanti le funzioni:
timeout /t -1
Che ci prolunga la pausa all'infinito, si interrompe solo nel momento in cui viene premuto un tasto della tastiera.
timeout -t 30 /nobreak
Che ci permette fa in modo il comando timeout non venga interrotto da nulla, unica combinazione di tasti che potrà fermarlo è la pressione combinata dei tasti Ctrl e C. Nel caso non si inserisca l'opzione /nobreak la pressione di un qualsiasi tasto ne blocca il funzionamento, passando lo sxript al passo successivo.

 Qualcun altro ha trovato altre soluzioni più efficienti?