Shell Scripting

Bucle for de Bash per mostrar l’hora cada segon

shell scripts


El bucle for és una de les primeres coses que aprens quan comences a escriure scripts de Bash. En aquest article en veurem un exemple molt senzill però útil: un script que escriu l’hora actual cada segon durant 15 minuts. Ens servirà per entendre com funciona el bucle, com es combina amb date i sleep, i quines maneres més modernes hi ha d’escriure’l.


L’script

#!/usr/bin/env bash
# rellotge.sh: escriu l'hora actual cada segon durant 15 minuts (900 vegades)

for i in $(seq 1 900); do
    date +%H:%M:%S
    sleep 1
done

Desa’l com a rellotge.sh, dona-li permís d’execució i executa’l:

$ chmod +x rellotge.sh
$ ./rellotge.sh
19:48:34
19:48:35
19:48:36
19:48:37
...

Per aturar-lo abans d’hora, prem Ctrl+C.


Com funciona

  • seq 1 900 genera la llista de números de l’1 al 900, un per línia.
  • for i in $(seq 1 900) recorre aquesta llista: la variable i pren cada valor i el bloc entre do i done s’executa 900 vegades. En aquest script no fem servir i per a res; només serveix per comptar les voltes.
  • date +%H:%M:%S escriu l’hora actual amb el format hores:minuts:segons. %H són les hores en format de 24 hores, %M els minuts i %S els segons.
  • sleep 1 atura l’script un segon abans de la volta següent.

900 voltes d’un segon fan 15 minuts.

L’script original escrivia seq 1 900 entre cometes inverses (accents greus), una sintaxi antiga que encara funciona. Avui es recomana $( … ), que és més llegible i es pot niar.


Altres maneres d’escriure el bucle

Bash no necessita seq per comptar. Aquestes dues formes fan el mateix sense executar cap programa extern:

# Rang amb claus
for i in {1..900}; do
    date +%H:%M:%S
    sleep 1
done

# Bucle aritmètic, a l'estil de C
for ((i = 1; i <= 900; i++)); do
    date +%H:%M:%S
    sleep 1
done

El rang {1..900} no admet variables ({1..$n} no funciona), però el bucle aritmètic sí. Per això és el més pràctic si vols que el nombre de voltes sigui un paràmetre:

#!/usr/bin/env bash
# rellotge.sh [VEGADES]: escriu l'hora cada segon (per defecte, 900 vegades)

vegades=${1:-900}
for ((i = 1; i <= vegades; i++)); do
    printf '%(%H:%M:%S)T\n' -1
    sleep 1
done

Aquí printf '%(%H:%M:%S)T\n' -1 fa el mateix que date +%H:%M:%S, però és una funció interna de Bash (des de la versió 4.2): l’argument -1 vol dir «l’hora actual» i el format és el mateix que el de date. Com que no ha d’executar cap programa extern, és més ràpid.


Un detall: el temps no és exacte

Cada volta dura una mica més d’un segon: el sleep 1 més el temps d’executar date. En una prova, 10 voltes amb date van durar 10,07 segons. Vol dir que, en 900 voltes, l’script acaba uns segons més tard dels 15 minuts, i de tant en tant pot saltar-se un segon a la sortida. Per a un rellotge o un registre informal no importa; si necessites precisió, calcula el temps a partir del rellotge del sistema, com fem al compte enrere del descans.


Usos pràctics

  • Desar el registre en un fitxer i veure’l alhora en pantalla: ./rellotge.sh | tee registre_hora.txt.
  • Afegir-hi la data: date '+%F %T' escriu 2026-10-04 19:48:34, més útil si el registre dura dies.
  • Marcar el temps d’una prova: executa’l en un terminal mentre en un altre fas proves, i tindràs una referència de quan ha passat cada cosa.
  • Vigilar una comanda cada segon: si el que vols és repetir una comanda i veure’n només l’última sortida, watch -n 1 date ho fa sense escriure cap script.
  • Bucle sense fi: si no vols cap límit, while true; do date +%T; sleep 1; done corre fins que el pares amb Ctrl+C.

Amb quatre línies, aquest exemple et mostra la base de molts scripts: repetir una acció un nombre de vegades, amb una pausa entre l’una i l’altra.

Posts relacionats