Ja tens informe-diari.sh programat a les 06:30 i estat-servei.sh cada 10 minuts. Aquesta lliçó no és cron una altra vegada: és l'altra meitat del problema. Programar un script és fàcil; el difícil és que aquell script estigui escrit per executar-se sense ningú al davant. Un script pensat per a una persona en un terminal dona per fet que algú pot contestar una pregunta, veure un avís a la pantalla, prémer Ctrl+C si es penja i tornar-lo a llançar si falla. A les 06:30 de la matinada no hi ha res d'això. Convertirem «executar-se sol» en una llista de set propietats concretes i les implementarem una a una fins a deixar informe-diari.sh veritablement desatès.
Contingut
- Les set propietats d'una tasca desatesa
- No interactiva: res per preguntar
- Idempotent: executar-la dues vegades no fa mal
- Exclusiva: una de sola alhora
- Observable: explicar què ha fet
- Acotada i segura davant fallades
- Configurable:
--dry-runi--force - Notificar, no heretar l'entorn i documentar
- Aplicació:
informe-diari.sha punt per a producció
- Les set propietats d'una tasca desatesa
Cada propietat respon a una pregunta que només apareix quan no hi ha ningú mirant:
| # | Propietat | Pregunta que respon | Eines |
|---|---|---|---|
| 1 | No interactiva | I si pregunta alguna cosa i ningú no contesta? | Opcions, configuració, [[ -t 0 ]] |
| 2 | Idempotent | I si s'executa dues vegades? | mkdir -p, escriptura atòmica, marques |
| 3 | Exclusiva | I si l'anterior segueix viva? | flock |
| 4 | Observable | Com sé demà si va funcionar? | Codis de sortida, registre amb marca de temps |
| 5 | Acotada | I si es penja per sempre? | timeout, reintents limitats |
| 6 | Segura davant fallades | I si falla a mitges? | set -euo pipefail, trap |
| 7 | Configurable | Com la provo sense trencar res? | --dry-run, --force |
Cap no és opcional: a un script automàtic al qual li falti una, tard o d'hora li passarà l'incident que aquella propietat evitava.
- No interactiva: res per preguntar
La regla és absoluta: un script automàtic no pregunta res. Tot el que un humà decidiria arriba per una de tres vies: opcions de línia d'ordres (03-05) per al que canvia a cada execució, fitxer de configuració (05-06) per al que és estable a cada màquina, i variables d'entorn per al que injecta qui el llança (cron, systemd, un contenidor). I un read en automàtic no falla de manera neta: es queda esperant. Si l'entrada estàndard està tancada, retorna error i amb set -e l'script mor amb un missatge incomprensible; si hi ha alguna cosa, se la menja i continua amb un valor absurd. La defensa activa és detectar que no hi ha terminal i negar-se a preguntar:
confirma() {
local resposta
[[ -t 0 ]] || { veloz_log_error "cal confirmar i no hi ha terminal; fes servir --force"; return 1; }
read -r -p "$1 [s/N] " resposta
[[ ${resposta,,} == s ]]
}[[ -t 0 ]] comprova si el descriptor 0 està associat a un terminal (05-05). Sota cron no ho està, així que la funció retorna 1 amb un missatge clar en lloc de penjar-se. Comprova-ho tu mateix: [[ -t 0 ]] && echo si || echo no respon si al teu terminal i no si ho executes com echo | bash -c '…'. El seu germà [[ -t 1 ]] serveix per decidir si acolorir la sortida: amb colors en un fitxer de registre acabes amb \033[31m per tot arreu.
- Idempotent: executar-la dues vegades no fa mal
Idempotent significa que executar l'operació un cop o cinc deixa el sistema en el mateix estat. És la propietat que fa segur un reintent, i en automatització els reintents són constants: cron s'encavalca, algú torna a llançar a mà després d'una fallada, el canvi d'hora duplica una execució (07-01), una tasca mor a mitges.
| No idempotent | Idempotent | Per què |
|---|---|---|
mkdir /srv/veloz/informes |
mkdir -p /srv/veloz/informes |
-p no falla si ja existeix |
echo "$linia" >> resum.txt |
printf '%s\n' "$linia" > resum.txt |
>> duplica en repetir |
ln -s origen desti |
ln -sfn origen desti |
-f reemplaça l'enllaç existent |
Quatre patrons ho resolen gairebé tot. (a) Operacions ja idempotents per disseny: mkdir -p, rm -f, ln -sfn, install -d, rsync; prefereix-les sempre. (b) Comprovar abans d'actuar, retornant 0, no error —«ja estava fet» és èxit, i un script que retorna error per això generarà una alerta falsa cada nit—. (c) Escriptura atòmica: temporal més mv, el patró més important dels quatre:
[[ -f $desti ]] && { veloz_log_info "l informe de $data ja existeix"; return 0; } # (b)
tmp=$(mktemp "${desti}.XXXXXX") || veloz_morir 1 "no puc crear el temporal" # (c)
generar_informe > "$tmp"
mv -f "$tmp" "$desti" # reanomenat atomic dins del mateix sistema de fitxersEscriure directament sobre $desti el deixa a mitges si l'script mor, i un altre procés pot llegir escombraries. Amb temporal més mv, el destí o és l'antic complet o és el nou complet, mai un híbrid, perquè rename(2) és atòmic. La condició és que el temporal estigui al mateix sistema de fitxers; per això el mktemp fa servir el directori del destí i no /tmp. (d) Marques de feina feta per a tasques cares: un fitxer testimoni ([[ -e $marca ]] && exit 0) que es crea només en acabar amb èxit.
- Exclusiva: una de sola alhora
Ja vas veure flock a 05-02 i el seu ús com a embolcall al crontab (flock -n /var/lock/veloz.lock ordre). La pregunta ara és on posar-lo, i hi ha dues respostes: al crontab, que és una línia i no toca l'script; o dins del mateix script, que el protegeix es llanci com es llanci —des de cron, a mà, des d'un temporitzador o des d'un altre script—. Per a una tasca important, la segona és la correcta:
pren_pany() {
exec 9>/var/lock/veloz-informe.lock || veloz_morir 1 "no puc obrir el pany"
flock -n 9 || { veloz_log_info "hi ha una altra execucio en curs; surto sense fer res"; exit 0; }
}Tres detalls que s'escapen. exec 9> obre el descriptor 9 per a tota la vida de l'script, i el pany s'allibera sol quan el procés acaba: no cal deixar-lo anar ni al trap. flock -n no espera (amb flock -w 30 9 esperaries 30 segons per si l'anterior està acabant). I aquí surt amb exit 0, no amb error, perquè «ja hi ha una execució en marxa» és comportament normal, no una avaria que mereixi alerta. El fitxer de pany va a /var/lock o /run/lock, mai dins del directori de dades que la tasca manipula.
- Observable: explicar què ha fet
Si demà no pots respondre «s'ha executat, quant ha trigat i què ha fet?» mirant un fitxer, la tasca no és observable. Calen tres coses. Codis de sortida significatius, reprenent la taula de 05-03: 0 és tot bé —inclòs «ja estava fet»—, 64 error d'ús, 65 dades d'entrada corruptes, 69 servei no disponible, 75 fallada temporal i 78 error de configuració. Així qui hi crida decideix sense llegir el text: 75 es reintenta amb retrocés, 64 i 78 s'han d'arreglar a mà.
Missatges amb marca de temps i nivell, perquè echo "començant" no serveix en un registre de tres mesos:
veloz_log() { printf '%s [%s] %s\n' "$(date -Is)" "$1" "${*:2}" >&2; }
veloz_log INFO "processats 1284 enviaments" # 2026-08-03T06:30:04+02:00 [INFO] processats 1284 enviamentsdate -Is dona la marca ISO-8601 amb zona horària, que ordena bé alfabèticament i no és ambigua. El disseny complet del registre —nivells, llindars, component, rotació— és el tema de 07-04. I un resum final llegible: l'última línia ha de permetre jutjar l'execució d'un cop d'ull (FI ok: 1284 enviaments, 37 incidencies, 12s, sortida $desti).
- Acotada i segura davant fallades
Una tasca que es penja és pitjor que una que falla: no avisa, ocupa el pany, bloqueja les següents i acumula processos durant dies. Tot el que parli amb l'exterior necessita un límit de temps, i en dos nivells que es complementen: timeout 30s curl … dins de l'script per tallar l'operació concreta amb un codi tractable, i timeout 300s /cami/script.sh des del crontab com a xarxa de seguretat. timeout retorna 124 quan talla, i el teu script ho ha de distingir d'una fallada normal. Els reintents, a més, van limitats i amb retrocés, reprenent 05-03:
reintenta() { # reintenta N ordre...
local intents="$1" espera=2 i; shift
for (( i = 1; i <= intents; i++ )); do
"$@" && return 0
(( i < intents )) && { sleep "$espera"; espera=$(( espera * 2 )); }
done
veloz_log ERROR "esgotats els $intents intents de: $*"; return 75
}Tres coses el fan correcte: hi ha un màxim d'intents (un while true reintentant eternament és una altra manera de penjar-se), l'espera es duplica per no castigar un servei que ja pateix, i l'última fallada retorna 75 (EX_TEMPFAIL), que li diu a qui crida «això pot ser transitori».
La capçalera del Mòdul 5 segueix sent la base —set -euo pipefail— i la neteja garantida amb trap importa aquí el doble: ningú no esborrarà a mà el temporal de 400 MB que ha quedat orfe.
TREBALL=$(mktemp -d "${TMPDIR:-/tmp}/informe.XXXXXX")
neteja() {
local codi=$?; rm -rf "$TREBALL"
(( codi == 0 )) && veloz_log INFO "FI ok" || veloz_log ERROR "FI amb error ($codi)"
exit "$codi"
}
trap neteja EXIT
# Error RECUPERABLE declarat explicitament: l'if ! neutralitza set -e per a aquella ordre
if ! metriques=$(veloz_api_get /metricas); then
veloz_log WARN "sense metriques; l informe sortira sense la seccio de rendiment"
metriques='{}'; (( ++AVISOS ))
fiEl que separa un script automàtic madur d'un de fràgil és distingir l'error recuperable del fatal. Fatal: falta el CSV d'enviaments, no existeix el directori de sortida, falta jq → registrar, sortir amb codi i no continuar. Recuperable: una línia del CSV mal formada, l'API no contesta a /metricas → registrar com a WARN, comptar-ho, continuar i reflectir-ho al resum. Com que set -e avorta davant de qualsevol fallada, els recuperables s'han de declarar, i l'if ! és la manera de fer-ho (05-03). Un script que avorta per no poder llegir una mètrica opcional és tan dolent com un que tira endavant amb el CSV corrupte: la decisió és teva, ordre per ordre.
- Configurable:
--dry-run i --force
--dry-run i --forceUna tasca que esborra, mou o publica coses ha de poder executar-se en fals. --dry-run permet estrenar una tasca, verificar un canvi de configuració o entendre què faria avui, sense conseqüències. La implementació neta no és omplir el codi d'if, sinó un prefix:
SIMULAR=0; EXECUTA=() # array buit: no anteposa res
(( SIMULAR )) && EXECUTA=(echo "[SIMULACIO]")
"${EXECUTA[@]}" mv -f "$tmp" "$desti" # cada accio AMB EFECTE porta el prefix
"${EXECUTA[@]}" rm -f "$antic"En mode normal EXECUTA és buit i l'expansió desapareix per complet, així que s'executa mv … tal qual. En simulació s'expandeix a echo "[SIMULACIO]" mv …, que imprimeix l'ordre ([SIMULACIO] mv -f /tmp/informe.a3Kx9 /srv/veloz/informes/informe-2026-08-02.txt) en lloc d'executar-la. És l'idioma d'array de 04-03, i la regla és: només les ordres amb efecte porten el prefix; llegir, comptar i calcular es fan igual en tots dos modes, perquè la simulació sigui realista. --force n'és el complement: salta comprovacions i confirmacions, i és el que dona sortida a la funció confirma de l'apartat 2 —sense terminal i sense --force es nega; amb --force continua, mai al revés—.
- Notificar, no heretar l'entorn i documentar
Notificar. Ningú no llegeix registres que no fallen. Perquè una fallada arribi a un humà hi ha tres vies: correu (sortida no buida més MAILTO a cron, 07-01), logger cap al syslog (logger -t veloz-informe -p user.err "…"), i un fitxer d'estat que un altre sistema llegeix, que és el més versàtil i encaixa amb 06-05:
jq -n --arg quan "$(date -Is)" --argjson codi "$codi" --argjson avisos "$AVISOS" \
'{tasca:"informe-diari", quan:$quan, codi:$codi, avisos:$avisos}' > "$BASE/logs/estat-informe.json"Aquell fitxer converteix «la tasca ha funcionat» en una dada consultable: el vigilant de 07-04 pot avisar si l'última execució correcta té més de 26 hores. És l'única manera de detectar una tasca que no s'ha executat, cosa que un registre no dirà mai perquè no hi ha cap línia per escriure quan no passa res. No heretar l'entorn. Ja vas veure a 07-01 que cron dona un PATH mínim; la conclusió de disseny va més enllà: un script automàtic no ha de confiar en el que hereta, vingui de cron, de systemd o d'un ssh remot (07-06). Es protegeix en quatre línies al principi:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export LC_ALL=C # comparacions i ordenacions predictibles (06-03)
umask 027 # permisos consistents del que creï (02-03)
veloz_requereix jq awk curl flock # fallar al principi, no a mitges (05-06)Fixar el PATH a l'script i no al crontab té un avantatge: la garantia hi viatja i funciona igual des d'un temporitzador o des de SSH.
Documentar. Quan la tasca falli seran les 3 de la matinada i qui hi miri no seràs tu. El runbook mínim són quatre respostes a la capçalera de l'script, i costa cinc minuts escriure'l:
# QUE FA: agrega /srv/veloz/dades/enviaments.csv del dia anterior i publica l informe.
# QUAN: cada dia a les 06:30 (crontab de 'veloz' a srv-veloz-01).
# LOG: ~/veloz-ops/logs/informe.log | estat: logs/estat-informe.json
# SI FALLA: tornar a llancar amb --data AAAA-MM-DD es segur (es idempotent).
# Codi 65 = CSV corrupte, 69 = API caiguda, 64 = mala invocacio.
- Aplicació:
informe-diari.sh a punt per a producció
informe-diari.sh a punt per a produccióL'esquelet d'automatització complet; la lògica d'awk i jq ja la tens del Mòdul 6:
#!/usr/bin/env bash
# (aqui va el bloc de runbook de l'apartat 8)
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export LC_ALL=C; umask 027
readonly BASE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
. "$BASE/lib/comu.sh"
[[ -r $BASE/etc/veloz-ops.conf ]] && . "$BASE/etc/veloz-ops.conf"
DATA=$(date -d yesterday +%F); SIMULAR=0; FORCAR=0; EXECUTA=(); AVISOS=0
processa_opcions() {
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--dry-run) SIMULAR=1 ;;
-f|--force) FORCAR=1 ;;
--data) DATA="${2:?falta la data}"; shift ;;
*) veloz_morir 64 "opcio desconeguda: $1" ;;
esac
shift
done
[[ $DATA =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || veloz_morir 64 "data invalida: $DATA"
(( SIMULAR )) && EXECUTA=(echo "[SIMULACIO]")
}
main() {
processa_opcions "$@"
veloz_requereix awk jq curl
exec 9>/var/lock/veloz-informe.lock
flock -n 9 || { veloz_log_info "hi ha una altra execucio en curs"; exit 0; }
TREBALL=$(mktemp -d "${TMPDIR:-/tmp}/informe.XXXXXX"); trap 'rm -rf "$TREBALL"' EXIT
local desti="$INFORMES_DIR/informe-$DATA.txt"
[[ -f $desti && $FORCAR -eq 0 ]] && { veloz_log_info "informe de $DATA ja fet"; return 0; }
veloz_log_info "INICI informe de $DATA (simular=$SIMULAR)"
[[ -r $ENVIAMENTS_CSV ]] || veloz_morir 65 "no puc llegir $ENVIAMENTS_CSV"
if ! METRIQUES=$(timeout 20s veloz_api_get /metricas); then
veloz_log_error "sense metriques de l API; continuo sense aquella seccio"
METRIQUES='{}'; (( ++AVISOS ))
fi
genera_informe "$DATA" > "$TREBALL/informe.txt" # awk, del Modul 6
"${EXECUTA[@]}" mkdir -p "$INFORMES_DIR"
"${EXECUTA[@]}" mv -f "$TREBALL/informe.txt" "$desti"
publica_resum_json "$DATA" "$METRIQUES" "$AVISOS" # jq -n --arg, del Modul 6
veloz_log_info "FI ok: informe de $DATA a $desti ($AVISOS avisos)"
}
main "$@"Recorre el llistat buscant-hi les set: no interactiva (tot per opcions i configuració, cap read), idempotent (mkdir -p, la comprovació de $desti que retorna 0, temporal més mv atòmic), exclusiva (pany amb descriptor 9), observable (INICI i FI, codis 64/65, resum JSON), acotada (timeout 20s a l'API), segura davant fallades (set -euo pipefail, trap, CSV illegible fatal enfront de mètriques absents recuperables) i configurable (--dry-run, --force, --data).
La línia de crontab final és més curta que la de 07-01, perquè l'script ja es protegeix sol, i ara és possible provar abans d'instal·lar amb ~/veloz-ops/bin/informe-diari.sh --dry-run --data 2026-08-02:
30 6 * * * /usr/bin/timeout 900s /home/veloz/veloz-ops/bin/informe-diari.sh >> /home/veloz/veloz-ops/logs/informe.log 2>&1Errors Habituals i Consells
- Deixar un
read«només per si de cas». En automàtic penja el procés o retorna escombraries. Tot per opcions, configuració o entorn. - Confondre «ja estava fet» amb error. Retornar un codi diferent de 0 genera una alerta falsa cada nit i la gent deixa de mirar-les.
- Escriure directament sobre el fitxer final, o posar el temporal a
/tmp. El primer deixa el destí corrupte si falla a mitges; el segon fa que elmvdeixi de ser atòmic, perquè copia i esborra entre discos diferents. flocksense-nen una tasca periòdica. Les execucions s'acumulen esperant en lloc de descartar-se.- Reintentar sense límit ni retrocés, o cridar sense
timeout. Totes dues són maneres de penjar-se eternament, i la primera a més castiga el servei que ja està caigut. --dry-runque no simula del tot, o colors al registre. Si una ordre amb efecte s'hi cola sense el prefix la simulació menteix; i sense decidir el color amb[[ -t 1 ]]acabaràs amb seqüències d'escapada en un fitxer de tres mesos.- Consell: abans de programar una tasca nova, executa-la tres vegades seguides a mà. Si la segona i la tercera no són inofensives, encara no és idempotent i no està a punt per a cron.
Exercicis
Exercici 1. Aquest fragment pretén publicar el resum del dia. Assenyala els tres problemes que impedeixen executar-lo desatès i reescriu-lo.
read -p "Data a processar: " data
mkdir /srv/veloz/informes/$data
curl http://localhost:8080/metricas > /srv/veloz/informes/$data/metricas.jsonExercici 2. Escriu una funció veloz_escriu_atomic per a lib/comu.sh que rebi el camí de destí, llegeixi el contingut de l'entrada estàndard i el publiqui de manera atòmica, respectant el mode simulació mitjançant la variable SIMULAR.
Solucions
Solució 1. Els tres problemes: (a) el read penja l'script sense terminal; (b) mkdir sense -p falla a la segona execució i curl sense -sSf ni temps d'espera es pot penjar o desar una pàgina d'error com si fos JSON; (c) s'escriu directament al destí, així que una fallada a mitges deixa un JSON truncat. A més, la variable sense cometes es trencaria amb qualsevol valor amb espais (03-06).
data="${1:-$(date -d yesterday +%F)}"
[[ $data =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || veloz_morir 64 "data invalida: $data"
desti="/srv/veloz/informes/$data"; mkdir -p "$desti"
tmp=$(mktemp "$desti/metriques.XXXXXX") || veloz_morir 74 "sense temporal"
trap 'rm -f "$tmp"' EXIT
timeout 30s curl -sSf --connect-timeout 5 --max-time 25 http://localhost:8080/metricas > "$tmp" ||
{ veloz_log_error "sense metriques de $data"; exit 69; }
mv -f "$tmp" "$desti/metricas.json"La data arriba ara com a argument amb un valor per defecte assenyat (${1:-…} de 03-06), es valida amb =~ (05-04), i el trap garanteix que no quedin temporals encara que el curl falli.
Solució 2.
# veloz_escriu_atomic — publica stdin en un fitxer sense deixar-lo mai a mitges.
# Us: generar_alguna_cosa | veloz_escriu_atomic /cami/desti
veloz_escriu_atomic() {
local desti="${1:?falta el desti}" dir tmp
dir=$(dirname -- "$desti")
[[ -d $dir ]] || mkdir -p "$dir" || { veloz_log_error "no puc crear $dir"; return 74; }
if (( ${SIMULAR:-0} )); then
veloz_log_info "[SIMULACIO] escriuria $(wc -c) bytes a $desti"; return 0
fi
tmp=$(mktemp "$desti.XXXXXX") || { veloz_log_error "sense temporal al costat de $desti"; return 74; }
cat > "$tmp" && mv -f "$tmp" "$desti" && return 0
rm -f "$tmp"; veloz_log_error "fallada en publicar $desti"; return 74
}El mktemp es crea al costat del destí ("$desti.XXXXXX") i no a /tmp, que és la condició perquè el mv sigui un reanomenat atòmic i no una còpia entre discos. En mode simulació consumeix igualment l'entrada amb wc -c per no trencar la canonada que l'alimenta: si no llegissis stdin, el procés de l'esquerra rebria un SIGPIPE. I davant de qualsevol fallada s'esborra el temporal, deixant el destí anterior intacte.
Conclusió
Un script a punt per executar-se sol compleix set propietats. És no interactiva: zero read, tot per opcions, configuració o entorn, i [[ -t 0 ]] per negar-se a preguntar quan no hi ha ningú. És idempotent: mkdir -p, comprovar abans d'actuar retornant 0 quan ja estava fet, escriure a temporal i publicar amb mv atòmic, i marques per al que és car. És exclusiva: flock -n com a embolcall al crontab i, millor, amb exec 9> dins de l'script perquè el protegeixi es llanci com es llanci. És observable: codis que distingeixen tipus de fallada, línies amb date -Is i nivell, i un resum final que s'entén d'un cop d'ull. És acotada: timeout en dos nivells sobre tot el que parli amb l'exterior, i reintents amb màxim i retrocés. És segura davant fallades: set -euo pipefail, trap de neteja i una decisió conscient, ordre per ordre, sobre quin error és fatal i quin recuperable. I és configurable: --dry-run amb el prefix "${EXECUTA[@]}" per provar-la sense conseqüències, i --force per saltar-se les confirmacions que en automàtic no pot contestar ningú. A sobre d'això, dues coses que no són codi: no heretar l'entorn —fixa PATH, LC_ALL i umask, i comprova les eines en començar— i escriure el runbook mínim a la capçalera.
Amb la tècnica de tasques desateses a la mà, a 07-03 l'apliquem a l'operació que més s'agraeix haver automatitzat i pitjor es porta improvisar: la còpia de seguretat. Veuràs què s'ha de copiar i què no, la regla 3-2-1, la diferència entre còpia completa, incremental i diferencial, rsync --link-dest per a còpies incrementals que es restauren com a completes, polítiques de retenció, verificació amb sha256sum —perquè una còpia no verificada no és una còpia— i, sobretot, la part que gairebé ningú no prova fins que la necessita: la restauració. Neix ~/veloz-ops/bin/copia.sh.
Curs de Programació en Bash
Mòdul 1: Introducció a Bash
- Què és Bash?
- Configurar el teu Entorn
- Navegació Bàsica per la Línia d'Ordres
- Entendre el Shell
- Trobar Ajuda: man, help i --help
Mòdul 2: Ordres Bàsiques de Bash
- Operacions amb Fitxers i Directoris
- Ordres de Processament de Text
- Permisos i Propietat dels Fitxers
- Redirecció i Canonades
- Comodins i Expansió de Rutes
- Historial i Dreceres de Teclat
Mòdul 3: Fonaments de Scripting
- Crear i Executar un Script
- Variables i Constants
- Operadors Bàsics
- Sentències Condicionals
- Arguments i Entrada de l'Usuari
- Cometes, Expansió i Substitució
Mòdul 4: Scripting Intermedi
- Bucles en Bash
- Funcions en Bash
- Arrays i Arrays Associatius
- Manipulació de Cadenes
- La Sentència case i els Menús Interactius
- Aritmètica i Càlculs Numèrics
Mòdul 5: Tècniques Avançades de Scripting
- Operacions Avançades amb Fitxers
- Gestió de Processos
- Gestió d'Errors i Depuració
- Expressions Regulars
- Entrada/Sortida Avançada: Descriptors i Here-Documents
- Scripts Modulars i Llibreries Reutilitzables
Mòdul 6: Treballar amb Eines Externes
Mòdul 7: Automatització i Programació
- Tasques Cron
- Automatitzar Tasques
- Scripts de Còpia i Restauració
- Monitoratge i Registre
- Serveis i Temporitzadors amb systemd
- Automatització Remota amb SSH
Mòdul 8: Bones Pràctiques i Optimització
- Escriure Codi Llegible
- Optimitzar Scripts en Bash
- Consideracions de Seguretat
- Control de Versions amb Git
- Anàlisi Estàtica amb ShellCheck i shfmt
- Proves Automatitzades amb Bats
- Portabilitat: POSIX sh enfront de Bashismes
