Amb awk i sed el toolkit ja sap llegir, resumir i transformar qualsevol text que li posis al davant. Però tot aquest text continua venint de fitxers que algú va deixar al disc. Un script d'operacions necessita alguna cosa més: preguntar al mateix sistema en quin estat és —quant disc queda, quina càrrega suporta, qui hi ha connectat, quina versió de sistema operatiu corre, si veloz-api és viva— per poder decidir en funció de la resposta. Aquesta lliçó recorre les ordres que interroguen el sistema, quines són fiables per a un script i com convertir les seves respostes en llindars i decisions, que és el que separa un script que informa d'un que actua.

Contingut

  1. Identitat i context: qui soc i on soc
  2. Detectar la distribució correctament
  3. Temps i configuració regional
  4. Disc: df i du
  5. Memòria, CPU i càrrega
  6. /proc: la font fiable
  7. Emmagatzematge i fitxers oberts, a grans trets
  8. Usuaris i sessions
  9. Dependències: comprovar abans de fallar
  10. Preguntar pels serveis
  11. L'entorn del procés
  12. Retornar informació: stderr, logger i correu
  13. Llindars i decisions
  14. Aplicació: neix estat-servei.sh

  1. Identitat i context: qui soc i on soc

El primer que un script hauria de saber és amb quina identitat s'està executant, perquè d'això depèn que pugui llegir /var/log/veloz/ o reiniciar un servei:

Ordre Retorna Ús típic en un script
whoami Nom de l'usuari efectiu Missatges i registre
id -u UID numèric (0 = root) [[ $(id -u) -eq 0 ]] per exigir o prohibir root
id -nG Grups als quals pertany Comprovar accés a un recurs
hostname Nom curt de la màquina Identificar l'origen d'un informe
hostname -f Nom complet (FQDN) Correus i avisos
uname -s / -r / -m Nucli / versió / arquitectura Decisions per plataforma
uname -a Tot l'anterior junt Diagnòstic manual, no per analitzar

En un script, la comprovació s'escriu [[ $EUID -eq 0 ]] && veloz_morir 1 "no executis això com a root". $EUID és una variable de Bash i no llança cap procés, així que és preferible a $(id -u) dins d'un bucle. La regla d'or és la contrària a la intuïció: un script d'informes s'ha de negar a córrer com a root, perquè no ho necessita i qualsevol error seu s'amplifica (08-03).

  1. Detectar la distribució correctament

uname et diu el nucli (Linux), no la distribució. Per això existeix /etc/os-release, un fitxer estàndard a totes les distribucions modernes amb format CLAU=valor pensat per ser carregat des d'un script:

if [[ -r /etc/os-release ]]; then
    . /etc/os-release          # defineix ID, VERSION_ID, PRETTY_NAME, ID_LIKE...
    printf 'Sistema: %s (id=%s, versio=%s)\n' "$PRETTY_NAME" "$ID" "$VERSION_ID"
fi                     # -> Sistema: Ubuntu 24.04.1 LTS (id=ubuntu, versio=24.04)

Amb $ID (ubuntu, debian, fedora…) i $ID_LIKE es tria la branca correcta en un case (04-05) sense endevinar. Les alternatives que es veuen per aquí són pitjors: lsb_release -a llança un procés i moltes vegades no està instal·lat, i mirar si existeix /etc/debian_version és fràgil. Un matís de seguretat: carregar el fitxer amb . executa el seu contingut, cosa acceptable a /etc/os-release (propietat de root) però que no has de fer amb fitxers que pugui escriure qualsevol.

  1. Temps i configuració regional

uptime dona d'un cop d'ull quanta estona fa que la màquina és encesa i la seva càrrega; uptime -p ho diu en prosa i uptime -s dona la data d'arrencada, que és el que serveix per detectar una reinicialització inesperada. Per a dates, date ja es va fer servir a 04-06: recorda date +%F (2026-08-03), date +%s (època) i date -d 'yesterday' +%F. Les zones horàries es controlen per entorn: TZ=UTC date +'%F %T %Z' imprimeix 2026-08-03 17:42:10 UTC sense tocar la configuració de la màquina, i timedatectl mostra la zona del sistema i si està sincronitzat per NTP. Registrar en UTC estalvia disgustos: els canvis d'hora fan que una hora es repeteixi i una altra no existeixi, cosa que trenca informes i comparacions. I aquí entra una de les lliçons més rendibles del mòdul: LC_ALL=C als scripts. La configuració regional canvia el comportament de les eines, no només els missatges.

Sense LC_ALL=C (p. ex. ca_ES.UTF-8) Amb LC_ALL=C
sort ignora guions i majúscules segons les regles de l'idioma Ordre per byte, predictible
[a-z] a les regex pot incloure lletres accentuades [a-z] són 26 lletres
Els missatges d'error surten traduïts Surten en anglès, com esperen els grep de l'script
date imprimeix dc. 03 ag. Imprimeix Wed 03 Aug
Processament de fitxers grans més lent Notablement més ràpid

La conseqüència pràctica: si el teu script compara, ordena o busca patrons a la sortida d'una ordre, posa-li LC_ALL=C al davant. Si la seva sortida l'ha de llegir una persona, deixa-la en el seu idioma.

  1. Disc: df i du

df informa de l'espai per sistema de fitxers muntat; du mesura el que ocupa un directori concret. No són intercanviables: df pregunta al sistema de fitxers i és instantani, du recorre l'arbre i pot trigar minuts.

df -h /srv/veloz                      # llegible per humans: 1.9G, 87%
df -P /srv/veloz | awk 'NR==2 { gsub(/%/,"",$5); print $5 }'   # nomes el percentatge
du -sh /var/log/veloz                 # quant ocupa el directori de logs
du -sh /var/log/veloz/* | sort -h | tail -5   # els cinc mes grans

-P és l'opció clau per a scripts, i mereix explicació. Sense ella, df parteix la línia en dues quan el nom del dispositiu és llarg, i el teu awk '{print $5}' llegeix la columna equivocada d'una línia partida. -P (format POSIX) garanteix una línia per sistema de fitxers. Fixa't també que -h i el processament automàtic són incompatibles: 1.9G no es pot comparar amb > (04-06). Als scripts es fa servir df -P (blocs) o df -PBM per a megabytes, i -h només per al que llegeix una persona. sort -h sí que entén sufixos com 1.9G, i per això funciona amb du -sh.

  1. Memòria, CPU i càrrega

free -m mostra la memòria en megabytes, nproc el nombre de nuclis disponibles i uptime les càrregues al final de la línia. De free -m el número que importa és available, no free. Linux fa servir la memòria lliure com a memòria cau de disc, així que free gairebé sempre sembla baix i no significa res; available estima quanta n'hi ha realment disponible per arrencar alguna cosa nova. Un script que avisi amb free baix donarà falses alarmes cada dia.

La càrrega mitjana (load average) són tres números: mitjana de processos executables o esperant disc en 1, 5 i 15 minuts. La seva interpretació depèn del nombre de nuclis: una càrrega de 4 és còmoda en una màquina de 8 nuclis i greu en una de 2. Per això el llindar correcte no és mai un número fix, sinó una comparació amb nproc, i la que val per decidir és la de 5 o 15 minuts —la d'1 minut és massa nerviosa i dispara alertes per qualsevol pic—.

  1. /proc: la font fiable

Gairebé totes les ordres anteriors no són res més que lectors bonics de /proc, un sistema de fitxers virtual on el nucli publica el seu estat com a text pla. Llegir-lo directament és més ràpid (no llança processos) i molt més estable, perquè el format de /proc no canvia amb la versió de l'ordre ni amb l'idioma:

Font Conté Exemple de lectura
/proc/loadavg Les tres càrregues, processos i últim PID read -r c1 c5 c15 _ < /proc/loadavg
/proc/meminfo Memòria en kB, clau/valor awk '/^MemAvailable:/ { print $2 }' /proc/meminfo
/proc/cpuinfo Un bloc per nucli lògic grep -c ^processor /proc/cpuinfo
/proc/uptime Segons encès i ociós read -r seg _ < /proc/uptime
/proc/<pid>/status Estat, UID i memòria d'un procés grep VmRSS /proc/1234/status
/proc/<pid>/cmdline Ordre completa que el va llançar (amb \0) tr '\0' ' ' < /proc/1234/cmdline

Aquell read -r carrega1 carrega5 _ < /proc/loadavg de 03-05 no llança ni un sol procés i substitueix uptime | awk ...: dos processos menys i cap format que pugui canviar. És la diferència entre analitzar la sortida d'una ordre interactiva —pensada per a humans, susceptible de canviar de format, traduïda— i llegir una interfície del nucli, que és un contracte estable. Sempre que existeixi la segona opció, agafa-la.

  1. Emmagatzematge i fitxers oberts, a grans trets

lsblk mostra els discos i particions en forma d'arbre, amb els seus punts de muntatge i mides; lsblk -f hi afegeix el sistema de fitxers i l'UUID. mount (o millor, findmnt, que dona sortida tabulada i filtrable) llista el que hi ha muntat i amb quines opcions —comprovar que un /mnt/copia està muntat abans d'escriure-hi la còpia de seguretat evita omplir el disc arrel, un clàssic que veurem a 07-03—. I lsof llista fitxers oberts: lsof /var/log/veloz/acces.log diu quin procés el té obert, i lsof -p 1234 què té obert un procés. És l'eina per esbrinar per què no es pot desmuntar alguna cosa o qui reté un fitxer ja esborrat que continua ocupant disc.

  1. Usuaris i sessions

who llista les sessions obertes, w hi afegeix què està executant cadascuna i la càrrega, i last mostra l'històric de connexions i reinicis llegint /var/log/wtmplast -x reboot és la manera ràpida de veure quan es va reiniciar la màquina—.

Per consultar comptes, la temptació és grep alopez /etc/passwd, i és un error: només funciona si els usuaris són locals, i tan bon punt hi ha LDAP o un directori corporatiu retorna buit. La forma correcta és getent, que consulta les mateixes bases que el sistema (fitxer, LDAP, DNS…) segons /etc/nsswitch.conf:

Així, getent passwd alopez || veloz_morir 1 "l'usuari alopez no existeix" és una guarda vàlida en qualsevol màquina, i getent group veloz | cut -d: -f4 llista els membres del grup. És la mateixa ordre que a 06-04 servirà per resoldre noms de màquina amb getent hosts, i per això convé agafar-li estima: una interfície per a totes les bases de dades del sistema.

  1. Dependències: comprovar abans de fallar

Un script que fa servir jq i s'executa en una màquina sense jq falla a mitges, deixant fitxers temporals i feina a mig fer. Comprovar els requisits en arrencar és l'aplicació directa de les clàusules de guarda de 03-04:

veloz_requereix() {                      # a lib/comu.sh
    local falten=() cmd
    for cmd in "$@"; do
        command -v "$cmd" >/dev/null 2>&1 || falten+=("$cmd")
    done
    (( ${#falten[@]} == 0 )) || { veloz_log_error "falten ordres: ${falten[*]}"; return 127; }
}
veloz_requereix awk sed curl jq flock || exit 127

command -v és la forma correcta: és una ordre interna (no llança processos), és POSIX, i troba també funcions i àlies, a diferència de which, que és un executable extern, no és a tot arreu i retorna codis inconsistents. L'array acumula totes les que falten en comptes de morir a la primera, cosa molt més amable amb qui instal·la. El codi 127 és el que Bash fa servir per a «ordre no trobada» (05-03).

Per saber quina versió d'un paquet hi ha instal·lada, dpkg -l <paquet> a Debian/Ubuntu i rpm -q <paquet> a Red Hat/Fedora. Fes-los servir per a diagnòstic, no com a comprovació: el que importa al teu script és que l'ordre estigui disponible i funcioni, no com es va instal·lar.

  1. Preguntar pels serveis

Per saber si veloz-api és viva hi ha dues vies complementàries. pgrep (05-02) pregunta si el procés existeix; systemctl is-active pregunta si el gestor de serveis el considera actiu, cosa més fiable perquè té en compte reinicis i fallades:

if systemctl is-active --quiet veloz-api; then
    veloz_log_info "veloz-api actiu"
else
    veloz_log_error "veloz-api inactiu (estat: $(systemctl is-active veloz-api))"
fi

--quiet suprimeix la sortida i deixa només el codi de retorn, que és el que interessa en un if. Sense --quiet, is-active imprimeix active, inactive, failed o activating, útil per al missatge d'error. Per veure per què ha fallat, journalctl -u veloz-api -n 20 --no-pager mostra les últimes 20 línies del seu registre; --no-pager és imprescindible en un script, perquè si no journalctl intenta obrir less i es queda penjat esperant. El detall de systemd —unitats, temporitzadors, dependències— és la lliçó 07-05; aquí només es consulta.

  1. L'entorn del procés

env (o printenv) llista les variables exportades, i a srv-veloz-01 convé recordar que l'entorn de la teva sessió interactiva no és el que tindrà l'script quan el llanci cron (07-01): allà el PATH és mínim i HOME pot ser un altre. Aquesta diferència és la causa número u de «funciona al meu terminal i falla a cron».

env -i va a l'extrem contrari: executa una ordre amb un entorn completament buit, i és la manera de comprovar de què depèn realment el teu script:

env -i PATH=/usr/bin:/bin HOME="$HOME" ~/veloz-ops/bin/informe-diari.sh

Si l'script funciona amb aquesta línia, funcionarà a cron. És una prova de dos segons que estalvia una tarda de depuració.

  1. Retornar informació: stderr, logger i correu

Un script que interroga el sistema ha d'explicar el que ha vist, i hi ha tres destins segons qui escolta. El primer, ja conegut de 02-04, és stderr per als diagnòstics i stdout només per al resultat, de manera que informe-diari.sh > informe.txt no barregi avisos amb dades. El segon és el registre del sistema, amb logger:

logger -t veloz-ops -p daemon.warning "disc al 91% a /srv/veloz"

-t posa l'etiqueta amb què apareixerà al registre i -p la facilitat i la prioritat. L'avantatge respecte a escriure en un fitxer propi és que el missatge entra al mateix sistema que tota la resta —consultable amb journalctl -t veloz-ops, rotat i reenviable a un servidor central—. El tercer és el correu: mail -s "assumpte" [email protected] o sendmail llegeixen el cos de l'entrada estàndard, i són la forma tradicional que cron avisi. Els tres es combinen a l'estratègia de monitoratge de 07-04; aquí n'hi ha prou de saber que existeixen i que un script seriós no es limita a imprimir per pantalla.

  1. Llindars i decisions

Tot l'anterior són dades. El que converteix un script en una eina d'operacions és aplicar-los un llindar i actuar. Tres regles perquè els llindars no facin la punyeta:

  • Configurables, no incrustats. El 85 % de disc va a veloz-ops.conf (05-06), no dins de l'if.
  • Relatius quan l'absolut no diu res. La càrrega es compara amb nproc; els megabytes lliures, amb la mida del disc.
  • Amb marge. Un llindar que dispara amb 84,9 % i calla amb 85,1 % genera alertes intermitents. És preferible avisar un cop i no repetir fins que es creui de tornada amb folgança.
us_disc=$(df -P /srv/veloz | awk 'NR==2 { gsub(/%/,"",$5); print $5 }')
read -r carrega1 carrega5 _ < /proc/loadavg
mem_lliure=$(awk '/^MemAvailable:/ { printf "%d", $2/1024 }' /proc/meminfo)
nuclis=$(nproc)

(( us_disc > ${LLINDAR_DISC:-85} )) && veloz_log_error "disc al ${us_disc}%"
awk -v c="$carrega5" -v n="$nuclis" 'BEGIN { exit !(c > n) }' &&
    veloz_log_error "carrega $carrega5 per sobre de $nuclis nuclis"
(( mem_lliure < ${LLINDAR_MEM_MB:-512} )) && veloz_log_error "nomes ${mem_lliure} MB disponibles"

Fixa't en el truc de la càrrega: com que és un número decimal, (( )) no serveix (04-06), així que la comparació es delega en awk, el BEGIN { exit !(c > n) } del qual converteix el resultat en un codi de sortida —0 si es compleix— utilitzable directament en un &&. És el pont natural entre l'awk de 06-01 i la lògica de Bash. Aquesta bateria de comprovacions és exactament l'esquelet del projecte 09-01.

  1. Aplicació: neix estat-servei.sh

El toolkit guanya el seu segon executable. informe-diari.sh respon «què va passar ahir?»; estat-servei.sh respon «com està això ara?»:

#!/usr/bin/env bash
# estat-servei.sh — Estat de srv-veloz-01 i de veloz-api.
set -Eeuo pipefail
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$BASE_DIR/lib/comu.sh"
export LC_ALL=C

main() {
    veloz_requereix awk df systemctl || exit 127
    . /etc/os-release
    printf '== %s (%s) ==\n' "$(hostname -f)" "$PRETTY_NAME"
    printf 'Arrencada: %s | Usuari: %s\n' "$(uptime -s)" "$(whoami)"

    local us carrega5 nuclis estat
    us=$(df -P /srv/veloz | awk 'NR==2 { gsub(/%/,"",$5); print $5 }')
    read -r _ carrega5 _ < /proc/loadavg
    nuclis=$(nproc)
    printf 'Disc /srv/veloz: %s%% | Carrega 5m: %s de %s nuclis\n' "$us" "$carrega5" "$nuclis"

    if systemctl is-active --quiet veloz-api && pgrep -f veloz-api >/dev/null; then
        estat=actiu
    else
        estat=CAIGUT
        logger -t veloz-ops -p daemon.err "veloz-api no respon a $(hostname)"
    fi
    printf 'veloz-api: %s\n' "$estat"
    (( us > ${LLINDAR_DISC:-85} )) && { veloz_log_error "disc al ${us}%"; return 1; }
    [[ $estat == actiu ]] || return 1
    return 0
}
main "$@"

L'export LC_ALL=C del principi fixa el comportament de tot el que l'script invoqui, no només d'una ordre. La doble comprovació de systemctl i pgrep no és redundància gratuïta: systemd pot considerar activa una unitat el procés de la qual s'ha quedat zombi. I el codi de sortida final és el que fa útil l'script: estat-servei.sh || avisar funciona des d'un altre script, des de cron o des d'un temporitzador. El que encara no sap fer és comprovar si el port 8080 respon, que és diferent de que el procés existeixi: aquest buit el tanca la lliçó següent.

Errors Habituals i Consells

  • Analitzar df -h en un script. 1.9G no es compara amb números i la línia es pot partir. Fes servir df -P i, si de cas, -BM.
  • Mirar free en comptes d'available. Linux fa servir la RAM lliure com a memòria cau; free baix és el normal, no una alerta.
  • Fer servir which. No és POSIX, és un procés extern i els seus codis varien. command -v sempre.
  • Comparar la càrrega amb (( )). És decimal: (( 1.5 > 1 )) dona error de sintaxi. Delega-ho en awk.
  • grep a /etc/passwd. Només veu usuaris locals. getent passwd els veu tots.
  • Llindar de càrrega fix. Compara'l sempre amb nproc; 4 no significa el mateix en 2 nuclis que en 16.
  • journalctl sense --no-pager. L'script es queda penjat esperant less.
  • Consell: prefereix /proc/loadavg i /proc/meminfo a analitzar uptime o free: menys processos i un format que no canvia.
  • Consell: prova el teu script amb env -i PATH=/usr/bin:/bin ... abans de ficar-lo a cron; hi veuràs les dependències ocultes de l'entorn.

Exercicis

Exercici 1. Escriu una funció veloz_us_disc per a lib/comu.sh que rebi un punt de muntatge i retorni el seu percentatge d'ús com a número enter, sense %, funcionant encara que el nom del dispositiu sigui llarg i retornant codi 1 si el punt de muntatge no existeix.

Exercici 2. Escriu un fragment que comprovi si la càrrega mitjana de 15 minuts supera el nombre de nuclis i, en aquest cas, registri un avís al registre del sistema amb etiqueta veloz-ops i surti amb codi 1. La càrrega és decimal.

Exercici 3. Afegeix a estat-servei.sh un resum del sistema amb: distribució i versió, temps encès, nombre de sessions obertes, memòria disponible en MB i les tres particions més plenes. Fes servir les fonts més fiables de cada dada.

Solucions

Solució 1.

# veloz_us_disc — Percentatge d'us d'un punt de muntatge. Us: veloz_us_disc /srv/veloz
veloz_us_disc() {
    local punt="${1:?falta el punt de muntatge}"
    [[ -d "$punt" ]] || { veloz_log_error "no existeix: $punt"; return 1; }
    LC_ALL=C df -P "$punt" | awk 'NR==2 { gsub(/%/,"",$5); print $5+0 }'
}

-P garanteix una sola línia per sistema de fitxers, que és justament el cas que trenca la versió ingènua. gsub(/%/,"",$5) treu el símbol i $5+0 força el resultat a número, de manera que qui la crida pot fer-lo servir amb (( )) sense més neteja. LC_ALL=C davant de df —i no exportat— s'aplica només a aquesta ordre. Compte: si qui la crida fa servir set -e, convé invocar-la com us=$(veloz_us_disc /srv/veloz) || return 1.

Solució 2.

read -r _ _ carrega15 _ < /proc/loadavg
nuclis=$(nproc)
if awk -v c="$carrega15" -v n="$nuclis" 'BEGIN { exit !(c > n) }'; then
    logger -t veloz-ops -p daemon.warning "carrega 15m=$carrega15 supera $nuclis nuclis"
    exit 1
fi

/proc/loadavg té cinc camps (1min 5min 15min processos ultim_pid), així que el tercer s'agafa amb dos _ al davant. La comparació decimal va a awk: exit !(c > n) retorna 0 —èxit per a l'if— quan la condició és certa, perquè a awk exit 0 significa èxit i la negació ! converteix el vertader (1) en 0. És l'idioma estàndard per fer servir awk com a avaluador de condicions numèriques des de Bash.

Solució 3.

resum_sistema() {
    . /etc/os-release
    printf 'Sistema   : %s\n' "$PRETTY_NAME"
    printf 'Ences     : %s (des de %s)\n' "$(uptime -p)" "$(uptime -s)"
    printf 'Sessions  : %s\n' "$(who | wc -l)"
    printf 'Mem. disp.: %s MB\n' "$(awk '/^MemAvailable:/ { printf "%d", $2/1024 }' /proc/meminfo)"
    printf 'Particions mes plenes:\n'
    LC_ALL=C df -P -x tmpfs -x devtmpfs |
        awk 'NR>1 { gsub(/%/,"",$5); printf "  %-24s %3d%%\n", $6, $5 }' | sort -k2 -rn | head -3
}

Cada dada fa servir la seva font correcta: /etc/os-release en comptes de lsb_release, /proc/meminfo en comptes d'analitzar free, df -P en comptes de df -h. -x tmpfs -x devtmpfs exclou els sistemes de fitxers en memòria, que sempre apareixen al 0 % o al 100 % i només embruten el llistat. El sort -k2 -rn va després de l'awk perquè ordenar el percentatge ja net és trivial, mentre que ordenar la sortida crua de df amb el % enganxat no ho és.

Conclusió

Un script decideix bé quan pregunta bé. La identitat s'obté amb $EUID, id i whoami; el context, amb hostname -f, uname i sobretot /etc/os-release, que és la manera correcta de saber en quina distribució ets. El temps es maneja amb date, uptime -s i TZ, registrant en UTC, i LC_ALL=C fixa el comportament de sort, les regex i els missatges perquè l'script no depengui de l'idioma de la màquina. Els recursos surten de df -P (mai -h per processar), du -sh, free -m mirant available i nproc; però la font realment fiable és /procloadavg, meminfo, cpuinfo, <pid>/status—, un contracte del nucli que no canvia de format ni es tradueix, i que a més es llegeix sense llançar processos. getent consulta usuaris i grups vinguin d'on vinguin, command -v comprova dependències en arrencar en lloc de fallar a mitges, systemctl is-active --quiet i journalctl --no-pager interroguen els serveis, i env -i revela de quin entorn depèn el teu script abans que ho descobreixi cron. Tot plegat culmina en llindars configurables, relatius i amb marge que converteixen dades en decisions, amb awk com a avaluador quan el número és decimal.

estat-servei.sh ja sap dir si la màquina és sana i si el procés veloz-api existeix. Però «el procés existeix» i «el servei respon» no són el mateix: un procés pot ser viu i tenir el port 8080 tancat, bloquejat o inaccessible des d'una altra màquina. Per a això cal sortir del sistema local i mirar la xarxa: comprovar connectivitat i resolució de noms, veure quins ports estan escoltant, provar si un port respon —amb nc o amb el /dev/tcp que va quedar apuntat a 05-05— i esperar amb reintents que un servei s'aixequi. És la lliçó següent (06-04).

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