Parámetros y argumentos: $1, $@, $#, $?, shift, getopts

Introducción

Los scripts reciben información del exterior a través de los argumentos de la línea de comandos y de variables especiales que bash rellena automáticamente. Dominar estos mecanismos permite escribir scripts reutilizables y flexibles.

Parámetros posicionales


#!/usr/bin/env bash
# Ejecutar como: ./script.sh arg1 arg2 arg3

echo "Nombre del script: $0"
echo "Primer argumento:  $1"
echo "Segundo argumento: $2"
echo "Tercer argumento:  $3"
          

Para acceder a parámetros desde el décimo en adelante se necesitan llaves: {$10}, {$11}...

Variables especiales


$0    ← nombre del script (o del shell si no hay script)
$1..$N ← argumentos posicionales
$#    ← número total de argumentos
$@    ← todos los argumentos como palabras separadas (recomendado)
$*    ← todos los argumentos como una sola cadena
$?    ← código de salida del último comando (0=éxito, distinto de 0=error)
$$    ← PID del proceso actual (del script)
$!    ← PID del último proceso lanzado en background
$-    ← opciones activas del shell (set -e, etc.)
          

Diferencia entre $@ y $*:


#!/usr/bin/env bash
# Ejecutar: ./script.sh "primer argumento" segundo tercero

# $@ — cada argumento es una palabra separada (lo correcto)
for arg in "$@"; do
    echo "Argumento: $arg"
done
# Salida:
# Argumento: primer argumento
# Argumento: segundo
# Argumento: tercero

# $* — todos los argumentos juntos en una cadena
for arg in "$*"; do
    echo "Argumento: $arg"
done
# Salida:
# Argumento: primer argumento segundo tercero
          

Usar siempre "$@" para iterar argumentos — preserva los argumentos con espacios.

shift — Desplazar argumentos

shift descarta el primer argumento ($1) y desplaza todos los demás una posición hacia la izquierda. $2 pasa a ser $1, etc. Útil para procesar argumentos uno a uno en un bucle.


#!/usr/bin/env bash
while [ $# -gt 0 ]; do
    echo "Procesando: $1"
    shift
done
          

shift 2    # desplazar 2 posiciones de golpe
          

Validar argumentos

Siempre comprobar que el script recibe los argumentos necesarios antes de usarlos:


#!/usr/bin/env bash
if [ $# -lt 2 ]; then
    echo "Uso: $0 <origen> <destino>" >&2
    exit 1
fi

ORIGEN="$1"
DESTINO="$2"
echo "Copiando de $ORIGEN a $DESTINO"
          

getopts — Opciones estilo Unix

getopts permite procesar opciones con guión al estilo Unix (-v, -f fichero), igual que hacen comandos como ls -la o tar -czf.


#!/usr/bin/env bash
# Uso: ./script.sh [-v] [-f fichero] [-n nombre]

VERBOSE=0
FICHERO=""
NOMBRE=""

while getopts "vf:n:" opcion; do
    case $opcion in
        v) VERBOSE=1 ;;
        f) FICHERO="$OPTARG" ;;
        n) NOMBRE="$OPTARG" ;;
        ?) echo "Uso: $0 [-v] [-f fichero] [-n nombre]" >&2; exit 1 ;;
    esac
done

# Desplazar los argumentos procesados
shift $((OPTIND - 1))

[ $VERBOSE -eq 1 ] && echo "Modo verbose activado"
[ -n "$FICHERO" ] && echo "Fichero: $FICHERO"
[ -n "$NOMBRE" ] && echo "Nombre: $NOMBRE"
echo "Argumentos restantes: $@"
          

Reglas de getopts:

  • La cadena de opciones ("vf:n:") lista las letras válidas.
  • Un : tras la letra indica que esa opción requiere un argumento (guardado en $OPTARG).
  • $OPTIND contiene el índice del siguiente argumento a procesar.
  • El ? en el case captura opciones desconocidas.

$? — Código de salida

Cada comando devuelve un código de salida al terminar: 0 significa éxito, cualquier otro valor indica error. $? contiene el código del último comando ejecutado.


ls /tmp
echo $?          # 0 (éxito)

ls /no_existe
echo $?          # 2 (error: no existe)

grep "patron" fichero.txt
echo $?          # 0 si encontró, 1 si no encontró, 2 si error

# Usar $? directamente
if [ $? -eq 0 ]; then
    echo "El comando tuvo éxito"
fi

# Forma más idiomática (sin necesidad de $?)
if grep -q "patron" fichero.txt; then
    echo "Patrón encontrado"
fi
          

Importante: $? se sobreescribe con cada comando. Guardarlo en una variable si se necesita más tarde: RESULTADO=$?.

Para el examen LPIC-1: conocer $0, $1-$9, $#, $@, $?, $$ y el uso básico de shift y getopts.

Operadores y comparaciones: test, [ ], [[ ]]

Índice de la sección

Índice del curso