Al llarg del mòdul has escrit "$CAMI_CSV", "$@", ${data} i ${VELOZ_LLINDAR:-50} seguint instruccions, sense una explicació completa del perquè. Aquesta lliçó paga aquest deute, i no és cap detall menor: la immensa majoria dels bugs d'scripting a Bash —els que apareixen tres mesos després, amb un fitxer que tenia un espai al nom o una variable que va arribar buida— són problemes de cometes i expansió. Entendre l'ordre exacte en què Bash processa una línia és el que separa un script que funciona gairebé sempre d'un que funciona sempre.

Contingut

  1. L'ordre de les expansions
  2. Cometes dobles, simples i sense cometes
  3. Posar cometes sempre a les variables, i l'escapament amb \
  4. Expansió de paràmetres: valors per defecte i validació
  5. Substitució d'ordres i expansió aritmètica
  6. IFS i la divisió en paraules
  7. El desastre de for f in $(ls)
  8. printf davant d'echo
  9. Repàs final d'informe-diari.sh

  1. L'ordre de les expansions

Abans d'executar qualsevol ordre, Bash transforma la línia que has escrit seguint sempre la mateixa seqüència, i conèixer-la explica gairebé tota la resta:

flowchart LR
    A["Línia<br/>escrita"] --> B["1 Claus<br/>2 Titlla"]
    B --> D["3 Paràmetres<br/>$var"]
    D --> E["4 Ordres<br/>5 Aritmètica"]
    E --> G["6 Divisió<br/>en paraules"]
    G --> H["7 Comodins<br/>*.csv"] --> I["Ordre<br/>executada"]

Amb exemples concrets: les claus converteixen enviaments-{01,02}.csv en dos noms; la titlla converteix ~/veloz-ops en /home/joan/veloz-ops; els paràmetres converteixen $CAMI_CSV en el camí del CSV; la substitució d'ordres converteix $(date +%F) en 2026-08-03; l'aritmètica converteix $(( 3 * 4 )) en 12; la divisió en paraules parteix el resultat en arguments; i els comodins converteixen *.csv en els fitxers que existeixen.

La clau de tota la lliçó és a l'ordre dels passos 3 i 6. Bash primer substitueix la variable pel seu valor, i després parteix el resultat en paraules pels espais. És a dir: si una variable conté espais, aquests espais es converteixen en separadors d'arguments després que la variable hagi desaparegut.

fitxer="enviaments juliol.csv"
wc -l $fitxer      # Bash executa: wc -l enviaments juliol.csv   → DOS fitxers, error
wc -l "$fitxer"    # Bash executa: wc -l "enviaments juliol.csv" → UN, correcte

Les cometes dobles no impedeixen que la variable s'expandeixi; impedeixen el pas 6, la divisió en paraules. Aquest és tot el seu secret.

  1. Cometes dobles, simples i sense cometes

Bash ofereix tres nivells de protecció, i aquesta taula resumeix què passa a cadascun:

S'expandeix Sense cometes "Dobles" 'Simples'
Variables $var, $(cmd), $(( )) No
Escapament \ Parcial No
Divisió en paraules No No
Comodins * No No
Titlla ~ i claus {a,b} No No

Les files en negreta són les que importen: les cometes dobles expandeixen variables però bloquegen la divisió en paraules i els comodins, que és justament el que vols el 95% de les vegades.

ciutat="Sant Sebastià";  patro="*.csv"
echo $ciutat      # Sant Sebastià  (dos arguments que echo uneix amb un espai)
echo "$ciutat"    # Sant Sebastià  (un sol argument)
echo '$ciutat'    # $ciutat        (literal, sense expandir)
ls $patro         # llista els fitxers .csv reals (comodins actius)
ls "$patro"       # busca un fitxer anomenat literalment *.csv

Amb echo la diferència entre les dues primeres sembla cosmètica, però amb mkdir o rm és catastròfica: mkdir $ciutat crearia dos directoris, Sant i Sebastià. Les cometes simples, per la seva banda, són absolutes: res no s'expandeix a dins, ni tan sols la barra invertida. Són l'elecció correcta per a expressions regulars (05-04), patrons de sed (06-02) i qualsevol text que hagi d'arribar literal a un altre programa:

grep '^2026-08-03 .*\[ERROR\]' /var/log/veloz/app.log   # regex literal
awk -F, '{ print $3 }' /srv/veloz/dades/enviaments.csv   # $3 és d'awk, no de Bash

Si aquests patrons anessin amb cometes dobles, Bash intentaria expandir $3 com una variable —que estaria buida— i awk rebria { print }: una fallada silenciosa perfecta. Com que les cometes simples no admeten escapaments, per incloure-hi una cometa simple a dins cal tancar-les, escapar i reobrir: 'no'\''funciona' produeix no'funciona. És lleig, però és l'única manera.

  1. Posar cometes sempre a les variables, i l'escapament amb \

La norma professional és simple i gairebé no té excepcions: posa cometes a tota expansió de variable, sempre. Aquests són els tres desastres que evita. Camins amb espais: wc -l $fitxer es parteix en diversos arguments. Amb una ordre destructiva, rm -rf $directori sobre directori="/srv/veloz dades" esborraria /srv/veloz i dades.

Variables buides: en expandir-se sense cometes, una variable buida desapareix del tot en lloc de convertir-se en una cadena buida:

ciutat="";  patro="ERROR*"
[ $ciutat = "Bilbao" ]     # bash: [: =: s'esperava una expressió unària
[ "$ciutat" = "Bilbao" ]   # funciona: compara "" amb "Bilbao"
grep $patro app.log        # si existeix un fitxer ERRORS.txt, el patró es torna ell
grep "$patro" app.log      # el patró arriba intacte a grep

Sense cometes, test rep [ = Bilbao ] i no hi entén res, perquè el primer operand s'ha esfumat abans que el veiés. Recorda de 03-03 que [[ ]] hi és immune; [ ] no.

Comodins accidentals: és el cas de les dues últimes línies; si una variable conté * o ?, sense cometes Bash intenta expandir-la contra els fitxers del directori. És especialment traïdor perquè l'script funciona fins que algú crea un fitxer amb el nom equivocat al directori de treball.

Les úniques excepcions raonables són l'interior de [[ ]] a l'esquerra de l'operador, l'interior de (( )), i els casos en què vols deliberadament la divisió en paraules. Davant del dubte, posa cometes: posar cometes de més no ha trencat mai cap script; posar-ne de menys, cada dia.

Escapament amb la barra invertida

La barra invertida \ protegeix un únic caràcter del pas de processament següent:

Per exemple, echo "El cost és \$50" imprimeix El cost és $50, i a echo Fitxer:\ enviaments\ juliol.csv els espais escapats no separen paraules. Dins de cometes dobles, la barra invertida només té efecte sobre quatre caràcters: $, `, " i \ (i el salt de línia). Davant de qualsevol altre s'imprimeix literalment, de manera que echo "cami\nou" produeix cami\nou. Aquest detall sorprèn qui ve d'altres llenguatges: echo "\n" no imprimeix cap salt de línia a Bash per defecte. Per a això cal echo -e o, millor, printf (apartat 8).

Al final d'una línia, la barra invertida escapa el salt de línia mateix i permet partir ordres llargues, que és el que has vist a tots els scripts del mòdul. Compte: no hi pot haver ni un espai després de la \. Si n'hi ha, la barra escapa aquest espai en lloc del salt i l'ordre es trenca amb un error desconcertant.

  1. Expansió de paràmetres: valors per defecte i validació

La família ${var...} va molt més enllà de llegir un valor; aquestes cinc formes són les d'ús diari:

Forma Què fa
${var:-def} Retorna def si var és buida o no existeix. No modifica var
${var:=def} Retorna def i a més assigna def a var
${var:?msg} Si var és buida, escriu msg a stderr i avorta l'script
${var:+val} Retorna val només si var valor (el cas contrari)
${#var} Retorna la longitud de la cadena
ciutat=""
echo "${ciutat:-totes}"   # totes  (ciutat continua buida)
echo "${ciutat:=totes}"   # totes  (i ara ciutat val "totes")
echo "${#ciutat}"         # 5      (longitud de "totes")
echo "${CAMI_CSV:?falta el camí del CSV}"   # avorta: bash: CAMI_CSV: falta el camí...

${var:?} és la joia de la família per a scripts de producció: converteix una variable obligatòria sense valor en una mort immediata amb missatge clar, en lloc de deixar que l'script continuï endavant amb camins buits. Compara els dos escenaris: sense ell, rm -rf "$DIR_TEMPORAL/"* amb la variable buida es converteix en rm -rf /*. Amb ${DIR_TEMPORAL:?}, l'script mor abans d'arribar-hi.

${var:+val} sembla rebuscada, però resol molt bé la construcció d'opcions condicionals: filtre="${ciutat:+--ciutat $ciutat}" produeix --ciutat Bilbao si hi ha ciutat i una cadena buida si no. Un matís sobre els dos punts: ${var-def} (sense :) només aplica el valor per defecte si la variable no existeix, mentre que ${var:-def} l'aplica també si existeix però és buida; a la pràctica gairebé sempre vols la versió amb :.

Les operacions de manipulació de cadenes de la mateixa família —${var#patro}, ${var/a/b}, ${var^^}, ${var:0:5}— són la lliçó 04-04.

  1. Substitució d'ordres i expansió aritmètica

Ja fas servir $(ordre) des de 03-02; aquí van els tres matisos que faltaven. Posa-hi cometes sempre, pel mateix motiu que a les variables: el seu resultat pateix divisió en paraules. I s'imbrica sense escapaments, que és el seu gran avantatge sobre les cometes invertides:

fitxers=$(ls /srv/veloz/dades)
echo "$fitxers"    # respecta els salts de línia; sense cometes els torna espais
echo "Log més recent: $(basename "$(ls -t /var/log/veloz/*.log | head -1)")"

Fixa't que les cometes dobles internes de l'última línia funcionen perfectament: dins de $( ) comença un context nou, així que pots tornar a fer servir cometes dobles sense escapar-les. Amb `...` caldria escapar cada nivell, i amb dos nivells ja resulta il·legible.

L'expansió aritmètica $(( )) no necessita cometes internes però sí externes si el resultat es fa servir com a argument. Dins de $(( )) no hi ha divisió en paraules ni comodins —només aritmètica—, així que allà les variables van sense $ i sense cometes sense cap risc: és l'única zona de Bash on et pots relaxar.

  1. IFS i la divisió en paraules

IFS (Internal Field Separator) és la variable que diu a Bash per quins caràcters partir en paraules al pas 6. El seu valor per defecte són tres: espai, tabulador i salt de línia (comprova-ho amb printf '%q\n' "$IFS"). Canviar-lo permet dividir per un altre caràcter, cosa molt útil amb dades separades per comes:

linia="E-8821,2026-08-03,Bilbao,mgarcia,lliurat,34.90"
IFS=',' read -r id data ciutat repartidor estat import <<< "$linia"
echo "L'enviament $id de $repartidor a $ciutat està $estat"
# → L'enviament E-8821 de mgarcia a Bilbao està lliurat

Aquest IFS=',' read és el patró canònic per trossejar una línia de CSV, i té un detall important: en posar l'assignació davant de l'ordre, IFS només canvia durant aquesta invocació (lliçó 03-02) i es restaura sola després. Aquest és l'ús segur. Modificar IFS de manera global —una línia IFS=',' solta enmig de l'script— és perillós, perquè afecta tot el que vingui després i cal restaurar-lo a mà amb IFS=$' \t\n'. Si t'oblides de restaurar-lo, les ordres posteriors que depenguin de la divisió per espais es comportaran de manera inexplicable. La pràctica correcta és desar el valor original (IFS_ORIGINAL=$IFS) i tornar-l'hi, o encara millor, fer servir la forma d'una sola invocació.

  1. El desastre de for f in $(ls)

Aquest antipatró mereix el seu propi apartat perquè és l'error més repetit als scripts de principiant, i reuneix gairebé tots els conceptes de la lliçó. No escriguis mai for f in $(ls /srv/veloz/dades). Què hi falla, punt per punt:

  • Els noms amb espais es parteixen. enviaments juliol.csv produeix dues voltes del bucle, amb enviaments i juliol.csv. I els noms amb salt de línia (rars però legals) trenquen qualsevol suposició.
  • Els comodins s'apliquen al resultat. Si un fitxer es diu *, $(ls) el retorna i Bash l'expandeix contra el directori.
  • ls dona formats diferents segons si la seva sortida va a un terminal o a una canonada, i segons opcions i àlies de l'usuari. A més és un procés de més, del tot innecessari.

La solució correcta és fer servir els comodins directament, que Bash gestiona sense dividir en paraules:

for f in /srv/veloz/dades/*; do
    [[ -f "$f" ]] && wc -l "$f"
done

Cada $f és un nom complet encara que contingui espais, perquè els comodins produeixen una llista de paraules ja separades, no una cadena que calgui trossejar. Recorda de 02-05 que si el patró no casa amb res, sense nullglob el bucle fa una volta amb el patró literal; d'aquí la guarda [[ -f "$f" ]].

La mateixa lògica desaconsella for linia in $(cat fitxer): per recórrer línies es fa servir while IFS= read -r linia; do ... done < fitxer, que és la lliçó 04-01. Aquest IFS= buit al principi, per cert, evita que read retalli els espais de l'inici i el final de cada línia; juntament amb -r, forma l'idioma més segur per llegir text a Bash.

  1. printf davant d'echo

echo és còmode però no és predictible: el seu comportament amb opcions i barres invertides varia entre shells, entre versions i fins i tot segons l'opció xpg_echo. echo "-n" imprimeix -n o ho interpreta com una opció? echo "a\tb" produeix un tabulador o el text literal? Depèn del shell. printf és POSIX, uniforme a tot arreu, i a més dona control sobre el format:

Format Significat
%s / %d / %.2f Cadena / enter / decimal amb dues xifres
%-20s Cadena alineada a l'esquerra en 20 caràcters
%% / \n Percentatge literal / salt de línia (sempre interpretat)
printf '%-12s %6s %8s\n' "CIUTAT" "ENVIAM." "IMPORT"
printf '%-12s %6d %8.2f\n' "Bilbao" 148 3241.75    # → Bilbao          148  3241.75
printf '%-12s %6d %8.2f\n' "Valencia" 981 21470.30 # → Valencia        981 21470.30

Dues característiques molt útils. printf reutilitza el format fins a exhaurir els arguments, així que printf '%s\n' "$@" imprimeix cada argument a la seva pròpia línia. I %q escapa la sortida perquè sigui reutilitzable pel shell, cosa que la converteix en la millor eina per depurar valors amb espais: printf 'valor: %q\n' "$ciutat" imprimeix valor: Sant\ Sebastià.

Regla pràctica: echo per a missatges simples i interactius, printf en scripts seriosos, i sempre printf quan el format importi o el contingut pugui començar per guió.

  1. Repàs final d'informe-diari.sh

Tanquem el mòdul revisant l'script amb tot el que hem après. Aquestes són les correccions que aplica la versió definitiva:

#!/usr/bin/env bash
# informe-diari.sh - Resum diari de Veloz Envíos [--data D] [--ciutat C] [-v]
readonly CAMI_APP_LOG="${VELOZ_APP_LOG:?falta definir el camí d'app.log}"
readonly CAMI_CSV="${VELOZ_CSV:?falta definir el camí d'enviaments.csv}"
readonly DIR_INFORMES="${VELOZ_LOGS:-$HOME/veloz-ops/logs}"
readonly LLINDAR_ERRORS="${VELOZ_LLINDAR:-50}"
us() { printf 'Ús: %s [-f AAAA-MM-DD] [-c CIUTAT] [-v] [-h]\n' "$(basename "$0")"; }

data="$(date +%F)"
ciutat="${VELOZ_CIUTAT:-totes}"
detallat="no"
while [[ $# -gt 0 ]]; do
    case "$1" in
        -f|--data)     data="${2:?--data requereix un valor}";    shift 2 ;;
        -c|--ciutat)   ciutat="${2:?--ciutat requereix un valor}"; shift 2 ;;
        -v|--detallat) detallat="si"; shift ;;
        -h|--help)     us; exit 0 ;;
        *) printf 'ERROR: opció desconeguda %q\n' "$1" >&2; us >&2; exit 2 ;;
    esac
done

[[ -r "$CAMI_APP_LOG" && -s "$CAMI_CSV" ]] \
    || { printf "ERROR: no puc llegir les dades d'origen\n" >&2; exit 3; }
mkdir -p "$DIR_INFORMES" || exit 5
total_errors="$(grep -c "^$data .*ERROR" "$CAMI_APP_LOG")"
printf '%-18s %s\n' "INFORME VELOZ" "$data"
printf '%-18s %s (llindar %s)\n' "Errors del dia:" "$total_errors" "$LLINDAR_ERRORS"
[[ "$detallat" == "si" ]] && grep "^$data .*ERROR" "$CAMI_APP_LOG" | tail -5
linies="$(grep ",$data," "$CAMI_CSV")"
[[ "$ciutat" != "totes" ]] && linies="$(printf '%s\n' "$linies" | grep ",$ciutat,")"
printf '%s\n' "$linies" | cut -d, -f5 | sort | uniq -c | sort -rn
exit 0

Els canvis respecte a la versió de 03-05:

  • ${VELOZ_APP_LOG:?...} als camins obligatoris: si la configuració no els defineix, l'script mor a l'instant amb un missatge clar en lloc de treballar sobre camins buits. I ${VELOZ_LOGS:-$HOME/veloz-ops/logs} als opcionals, amb un valor per defecte assenyat.
  • ${2:?--data requereix un valor} dins del case, que substitueix la comprovació manual de 03-05 en una sola expressió.
  • Cometes absolutament a totes les expansions, incloses "$(date +%F)" i "$(grep -c ...)".
  • printf en lloc d'echo a tota la sortida, amb %q als missatges d'error perquè una opció amb caràcters estranys es vegi tal com ha arribat. En particular, printf '%s\n' "$linies": si una línia del CSV comencés per -n o contingués barres invertides, echo podria interpretar-la; printf '%s\n' mai.

Aquest últim punt il·lustra la mentalitat de la lliçó: no es tracta que l'script falli avui, sinó que no pugui fallar el dia que aparegui una dada inesperada. Un printf en lloc d'un echo costa quatre caràcters i elimina una classe sencera de bugs.

Errors Habituals i Consells

  • No posar cometes a una variable. Camins amb espais que es parteixen, variables buides que desapareixen, comodins accidentals. És l'error número u.
  • Fer servir cometes dobles en expressions regulars o d'awk. "$3" s'expandeix a res; fes servir cometes simples. I no esperis que echo "\n" imprimeixi un salt de línia: fes servir printf '\n'.
  • Deixar un espai després de la \ de continuació de línia. L'ordre es trenca i l'error no ho indica.
  • for f in $(ls). Fes servir comodins directes: for f in dir/*.
  • Modificar IFS sense restaurar-lo. Prefereix la forma IFS=',' read ..., que només afecta aquella invocació.
  • Confondre ${var:-x} amb ${var:=x}. El primer no toca la variable; el segon l'assigna. I no imbriquis cometes invertides: fes servir $( ), que s'imbrica sense escapaments.

Exercicis

Exercici 1 — Predigues la sortida. Amb ciutat="Sant Sebastià" i n=3, digues exactament què imprimeix cada línia i per què: (a) echo $ciutat; (b) echo "$ciutat"; (c) echo '$ciutat té $n lletres'; (d) echo "$ciutat té ${#ciutat} lletres"; (e) echo "Total: $(( n * 2 ))€".

Exercici 2 — Blindar un script perillós. Aquest fragment té sis problemes de cometes i expansió; troba'ls i reescriu-lo.

DIR_COPIA=$1
DATA=`date +%F`
for f in $(ls /srv/veloz/dades); do cp $f $DIR_COPIA/$f.$DATA; done
echo "Copiats `ls $DIR_COPIA | wc -l` fitxers"
rm -rf $DIR_COPIA/tmp/*

Exercici 3 — Informe alineat amb printf. Llegeix enviaments.csv i produeix una taula amb la ciutat alineada a l'esquerra en 12 caràcters, el nombre d'enviaments a la dreta en 6, i el percentatge sobre el total amb una xifra decimal. Fes servir printf i expansió aritmètica.

Solucions

Solució a l'Exercici 1

Línia Sortida Motiu
(a) i (b) Sant Sebastià A (a) es parteix en dos arguments, però echo els uneix amb un espai; a (b) és un sol argument
(c) $ciutat té $n lletres Cometes simples: no s'expandeix res
(d) Sant Sebastià té 13 lletres ${#ciutat} compta 13 caràcters, espai inclòs
(e) Total: 6€ L'aritmètica s'expandeix dins de les cometes dobles

El cas (a) és el parany didàctic: amb echo el resultat és idèntic al de (b), i per això molta gent conclou que les cometes són opcionals. Canvia echo per mkdir i (a) crearà dos directoris.

Solució a l'Exercici 2

Els sis problemes: (1) $1 sense cometes ni validació; (2) cometes invertides en lloc de $( ), dues vegades; (3) for f in $(ls ...); (4) totes les variables del cp sense cometes; (5) $f conté només el nom, no el camí, així que el cp falla llevat que siguis en aquell directori; (6) rm -rf $DIR_COPIA/tmp/* sense cometes ni validació és una bomba, perquè si $DIR_COPIA és buida es converteix en rm -rf /tmp/*.

readonly DIR_COPIA="${1:?Ús: $(basename "$0") DIRECTORI_DESTI}"
readonly DATA="$(date +%F)"
[[ -d "$DIR_COPIA" ]] || { printf 'ERROR: %q no és un directori\n' "$DIR_COPIA" >&2; exit 2; }
for f in /srv/veloz/dades/*; do
    [[ -f "$f" ]] || continue
    cp -a "$f" "$DIR_COPIA/$(basename "$f").$DATA"
done
printf 'Copiats %d fitxers\n' "$(find "$DIR_COPIA" -maxdepth 1 -type f | wc -l)"
rm -rf "${DIR_COPIA:?}/tmp/"*

L'última línia mereix una atenció especial: "${DIR_COPIA:?}" és l'idioma defensiu estàndard abans de qualsevol rm -rf, perquè si la variable fos buida l'script avorta amb un error en lloc d'executar un esborrat catastròfic a l'arrel. Costa cinc caràcters i ha salvat molts servidors.

Solució a l'Exercici 3. Compte amb un parany: Bash no fa decimals (03-02), així que la part entera i la decimal s'han de calcular per separat.

total=$(tail -n +2 "$CAMI_CSV" | wc -l)
printf '%-12s %6s %8s\n' "CIUTAT" "ENVIAM." "PERCENT."
tail -n +2 "$CAMI_CSV" | cut -d, -f3 | sort | uniq -c | sort -rn \
| while read -r n ciutat; do
    printf '%-12s %6d %6d.%d%%\n' "$ciutat" "$n" \
        "$(( n * 100 / total ))" "$(( n * 1000 / total % 10 ))"; done

La sortida alinea les columnes: Valencia, 981, 78.6%; Bilbao, 148, 11.8%. Fixa't en tres coses. El %% del format imprimeix un percentatge literal. El while read -r llegeix dos camps per línia, aprofitant que IFS divideix per espais exactament on uniq -c els deixa. I l'aritmètica entera obliga a aquesta gimnàstica de multiplicar per 1000 i treure el mòdul; a 06-01 veuràs que awk fa el mateix amb printf "%.1f%%" i sense acrobàcies.

Conclusió

Has tancat el buit que quedava. Saps en quin ordre expandeix Bash una línia, i que la divisió en paraules passa després de substituir les variables —el fet del qual es deriven gairebé tots els bugs de cometes—. Distingeixes amb precisió què expandeix cada tipus de cometa; poses cometes a tota variable per norma, sabent què es trenca si no ho fas; escapes amb \ sense caure en l'espai després de la continuació de línia; manejes ${var:-def}, ${var:=def}, ${var:?msg}, ${var:+val} i ${#var}; imbriques $( ) sense escapaments; entens IFS i el canvies només per invocació; has desterrat for f in $(ls) a favor dels comodins directes; i fas servir printf quan la sortida ha de ser predictible.

I amb això s'acaba el Mòdul 3. Repassa el camí: vas començar desant en un fitxer les canonades que teclejaves cada matí, i informe-diari.sh és avui una ordre de ~/veloz-ops/bin amb constants, validació d'entorn, codis de sortida documentats, opcions --data i --ciutat, --help, configuració per variables d'entorn i expansions blindades. Ha crescut en sis lliçons sense que cap versió trenqués l'anterior, que és exactament com creix el programari real. Els seus límits, això sí, es veuen a simple vista: l'script repeteix la mateixa canonada amb petites variacions, si volguessis l'informe de cada ciutat l'hauries d'invocar quatre vegades a mà, i no hi ha manera de reutilitzar en un altre script la lògica de validació que tant t'ha costat escriure.

Al Mòdul 4 arriben les eines que resolen això. Els bucles (04-01) recorreran ciutats, dates i fitxers; les funcions (04-02) empaquetaran la validació i el format per reutilitzar-los; els arrays (04-03) desaran llistes de repartidors i comptadors per ciutat; la manipulació de cadenes (04-04) completarà la família ${var...} que has començat avui; case (04-05) rebrà el tractament formal que aquí només has fet servir de passada; i l'aritmètica (04-06) resoldrà d'una vegada aquests percentatges amb decimals. informe-diari.sh deixarà de ser un guió lineal per convertir-se en un programa amb estructura.

Curs de Programació en Bash

Mòdul 1: Introducció a Bash

Mòdul 2: Ordres Bàsiques de Bash

Mòdul 3: Fonaments de Scripting

Mòdul 4: Scripting Intermedi

Mòdul 5: Tècniques Avançades de Scripting

Mòdul 6: Treballar amb Eines Externes

Mòdul 7: Automatització i Programació

Mòdul 8: Bones Pràctiques i Optimització

Mòdul 9: Projectes del Món Real

© Copyright 2026. Tots els drets reservats