Pregunta 1¿Qué sintaxis usa el predeterminado access.log cuando no se pasa un primer argumento?
Reporte de resumen de logs — argumentos, funciones y comandos combinados
Este artículo forma parte del Curso de Linux, con el que dominarás desde cero habilidades prácticas de Linux, desde los comandos básicos hasta los scripts de shell.
Recibe el log objetivo con log=${1:-access.log}, totalízalo con un bucle for más grep -c y awk '{sum+=$1}', y ciérralo todo con un reporte here-doc y un código de salida, ilustrado y practicado en una terminal del navegador.
Reunir las piezas en un solo script — el esqueleto de un reporte de resumen de logs
Todo lo que has aprendido hasta aquí — variables, parámetros posicionales ($1), condicionales ([ ] e if), bucles (for / while), funciones (name() { } y local), lectura de la entrada (while read … done < file), integración de comandos ($(...)) y salida (>> y here-doc) — se junta ahora en un solo script práctico.
El tema es el más habitual en producción: un reporte de resumen de logs.
Un script práctico recibe como argumentos el log objetivo y un umbral, comprueba la entrada, calcula los totales, reúne los resultados en un reporte y termina devolviendo un código de salida.
Para la agregación, combina comandos como grep para los conteos, awk para las sumas y sed para el formato; llevar el trabajo repetido a funciones y bucles lo mantiene legible.
Cuando un parámetro posicional viene vacío, complétalo con el predeterminado ${1:-access.log}.
vi mini.sh # abrir en el editor, escribir lo siguiente y guardar con :wq
# #!/bin/sh
# log=${1:-access.log} # predeterminado si no se pasa argumento
# count_status() { # función que devuelve el conteo de un código de estado
# grep -c " $1\$" "$log"
# }
# if [ ! -f "$log" ]; then # comprobación de la entrada
# echo "not found: $log" >&2
# exit 1
# fi
# for s in 200 403 500; do # totalizar por código de estado
# echo "$s : $(count_status $s)"
# done
# exit 0
chmod +x mini.sh
| Elemento | Dónde se usa en este script | Ejemplo |
|---|---|---|
Variable name=... | Tener en un solo sitio el nombre del log, el destino y el umbral | log=${1:-access.log} |
Argumento $1 / ${1:-predet} | Recibir el log objetivo y el umbral desde la línea de comandos | limit=${2:-1} |
Condición [ -f f ] / if | Comprobar que el log existe y determinar si se supera el umbral | if [ ! -f "$log" ]; then exit 1; fi |
Bucle for / while read | Totalizar por código de estado y leer línea por línea | for s in 200 403 500; do … done |
Función name() { … } | Agrupar la agregación bajo un nombre y reutilizarla | count_status() { grep -c " $1\$" "$log"; } |
Lectura de entrada while read … < f | Leer el log línea por línea y contar por URL | while read line; do … done < "$log" |
Integración $(grep -c …) / awk | Capturar conteos y sumas con sustitución de comandos | n=$(grep -c ' 500$' "$log") |
Salida >> / here-doc | Escribir los valores agregados como un reporte de formato fijo | cat > "$out" <<REPORT … REPORT |
Leer la entrada y cerrar con la integración — while read junto a grep / awk / sed
El trabajo fino, línea por línea, se hace con while read line; do … done < file.
Combina eso dentro de una función con grep para filtrar cada línea, awk para totalizar columnas y sed para uniformar el formato, y podrás reutilizar la lógica de agregación como un componente.
Añade un formateo como sed 's/^GET /[GET] /' y el reporte mantiene un aspecto uniforme.
Para terminar, incrusta los valores agregados en un reporte fijo con un here-doc, añade un aviso y devuelve exit 1 cuando se supere el umbral, o devuelve exit 0 cuando todo esté bien.
Recibe el segundo argumento como umbral con ${2:-100} y compara números como en if [ "$err" -gt "$limit" ], y tendrás un reporte con diagnóstico que puedes usar en producción.
El cierre es combinar el `grep` / `awk` / `sed` que aprendiste en los fundamentos con las estructuras de control de un script de shell.
vi scan.sh # abrir en el editor, escribir lo siguiente y guardar con :wq
# #!/bin/sh
# log=${1:-access.log}
# limit=${2:-1}
# err=$(grep -c ' 500$' "$log") # obtener el conteo de 500 con integración
# while read line; do # leer línea por línea
# echo "$line" | sed 's/^/log: /' # dar formato e imprimir
# done < "$log"
# if [ "$err" -gt "$limit" ]; then # comprobar contra el umbral
# echo "WARN: too many 500"; exit 1
# fi
# exit 0
chmod +x scan.sh
while read va tomando las líneas de una en una, y combinarlas con grep / awk / sed las convierte en un reporte con diagnóstico.Decidir el resultado según un umbral pasado como argumento — agregación y códigos de salida juntos
Junta en un solo script la recepción de argumentos y la agregación de la primera parte con el diagnóstico y el código de salida de la segunda, y tendrás un reporte que marca alerta o normal y que puedes usar en producción.
Recibe el umbral en el primer argumento; cuando el conteo agregado por grep -c o awk sea igual o mayor, avisa y devuelve exit 1, y cuando esté por debajo, trátalo como normal y devuelve exit 0.
Quien llama al script puede determinar el éxito o el fallo a partir de ese código de salida.
En la comparación numérica -gt significa mayor que y -ge significa mayor o igual, lo que cambia cómo se trata un valor situado justo en el umbral.
El [ "$err" -gt "$limit" ] de la Práctica 2 no se cumple cuando el conteo es igual al umbral, mientras que el [ "$err" -ge "$limit" ] de la Práctica 3 avisa incluso con un valor igual.
Esa diferencia es la que decide el resultado justo en el valor límite, así que elige el operador que encaje con tu propósito.
-ge compara el conteo agregado con el umbral: si es igual o mayor, avisa y devuelve exit 1; si es menor, es normal y devuelve exit 0.Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Qué sintaxis lee un archivo línea por línea y lo procesa?
Pregunta 3¿Cómo le avisas a quien llamó al script de que algo va mal cuando se supera el umbral?