Cargando...

Shell 101

Publicación: Junio 2, 2026
Última revisión: Julio 13, 2026

¿Qué es programación en Shell?

Shell es una interfaz de línea de comando; es decir una forma en la que el usuario puede interactuar con software (aplicaciones específicas) y el sistema operativo por medio de comandos escritos y respuestas dentro de una consola. Es dependiente completamente de inputs desde el teclado y outputs en texto

Poder programar en shell para un programador es como adquirir un nuevo tipo de superpoder ✨ ya que nos permitirá automatizar tareas, manejar procesos, detener ataques (o también atacar, shhh) y más importante: administrar y monitorear efectivamente un sistema.

Así como existen diferentes lenguajes de programación, existen diferentes tipos de Shell; cada uno con comandos propios, herramientas y características. Las más común para Linux es Bash (Bourne Again Shell), para macOS Zsh y para Windows es PowerShell.

¿Cómo saber qué shell tengo en mi equipo?

PowerShell → echo $ShellId

PS C:\Users\Cardui> echo $ShellId
Microsoft.PowerShell

Linux y macOS → echo $SHELL

Arch Linux

[root@alarm /]# echo $SHELL
/bin/bash

macOS

vanessa@MacBook-Air-de-Vanessa Desktop % echo $SHELL
/bin/zsh

En esta ocasión nos enfocaremos en Shell scripting con bash

¿Cómo creo un archivo de Bash?

Un archivo de bash puede iniciar con #!/path/to/interpreter

Ejemplo: #!/bin/bash

Creemos un archivo de bash:

  1. Creamos el archivo → nano test.sh
  2. Dentro del editor nano
#!/bin/bash

echo "Weeenas universo"
echo "The current bash version is: ${BASH_VERSION}"

Lo guardamos con ctrl + X

  1. Nos otorgamos permiso para ejecutar el archivo → chmod 711 test.sh
  2. Ejecutamos con ./
[root@alarm CarduiDocs]# ./test.sh 
Weeenas universo
The current bash version is: 5.1.16(1)-release
  • Por qué permisos 711?

    Los permisos se representan por valores octales que indican los permisos sobre el archivo dependiendo del usuario. Los permisos se asignan numéricamente al sumarlos:

    r → read (leer) → 4

    w → write (modificar el archivo) → 2

    x → execute (ejecutar) → 1

    Owner (dueño del archivo) Grupo Otros (fuera del grupo)
    -rw r– r–
    6 4 4
    6 = 4 + 2 + 0 4 = 4 + 0 + 0 4 = 4 + 0 + 0
    Leer y escribir Sólo leer Sólo leer

    Por ejemplo, creé el archivo test.txt con el editor de texto en consola nano. Por default, este archivo tiene permisos 644. Es decir, sólo su dueño (yo) puedo escribir sobre él, los demás sólo pueden leerlo.

    vanessa@MacBook-Air-de-Vanessa Desktop % ll
    total 80840
    drwx------@  9 vanessa  staff       288 May  4 08:30 .
    drwxr-x---+ 46 vanessa  staff      1472 May  4 08:23 ..
    -rw-r--r--@  1 vanessa  staff      8196 May  2 08:23 .DS_Store
    -rw-r--r--   1 vanessa  staff         0 Jun 20  2025 .localized
    -rwxr-xr-x@  1 vanessa  staff   4612670 Mar  6  2017 Linux_Server_Security.pdf
    -rw-r--r--@  1 vanessa  staff   1091318 Apr 30 17:49 Screenshot 2026-04-30 at 17.48.56.png
    -rwxr-xr-x@  1 vanessa  staff  35660828 Jan 31  2009 linux_server_hacks.pdf
    drwxr-xr-x  11 vanessa  staff       352 May  2 08:23 old
    -rw-r--r--   1 vanessa  staff        26 May  4 08:30 test.txt
    vanessa@MacBook-Air-de-Vanessa Desktop % chmod 700 test.txt 
    vanessa@MacBook-Air-de-Vanessa Desktop % ll
    total 80840
    drwx------@  9 vanessa  staff       288 May  4 08:30 .
    drwxr-x---+ 46 vanessa  staff      1472 May  4 08:23 ..
    -rw-r--r--@  1 vanessa  staff      8196 May  2 08:23 .DS_Store
    -rw-r--r--   1 vanessa  staff         0 Jun 20  2025 .localized
    -rwxr-xr-x@  1 vanessa  staff   4612670 Mar  6  2017 Linux_Server_Security.pdf
    -rw-r--r--@  1 vanessa  staff   1091318 Apr 30 17:49 Screenshot 2026-04-30 at 17.48.56.png
    -rwxr-xr-x@  1 vanessa  staff  35660828 Jan 31  2009 linux_server_hacks.pdf
    drwxr-xr-x  11 vanessa  staff       352 May  2 08:23 old
    -rwx------   1 vanessa  staff        26 May  4 08:30 test.txt
    vanessa@MacBook-Air-de-Vanessa Desktop % 

Uso de variables

Variables de ambiente → Almacenar comandos o información que se usa repetidamente en el futuro

Imprimir variables de ambiente → printenv

Ejemplo Linux

[root@alarm CarduiDocs]# printenv
SHELL=/bin/bash
PWD=/CarduiDocs
LOGNAME=alarm
XDG_SESSION_TYPE=tty
SYSTEMD_EXEC_PID=328
MOTD_SHOWN=pam
HOME=/root
LANG=C
INVOCATION_ID=2e68610831a0475e913f5fb06ecef25a
XDG_SESSION_CLASS=user
TERM=vt220
USER=alarm
SHLVL=3
XDG_SESSION_ID=1
XDG_RUNTIME_DIR=/run/user/1000
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
MAIL=/var/spool/mail/alarm
OLDPWD=/
_=/usr/bin/printenv

Ejemplo macOS

vanessa@MacBook-Air-de-Vanessa Desktop % printenv
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/zsh
TERM=xterm-256color
TMPDIR=/var/folders/59/_drbhfms24j_k5_xhs88jhbw0000gn/T/
TERM_PROGRAM_VERSION=470.2
TERM_SESSION_ID=8F63D89F-A1A1-44BA-BEAE-002951646D05
USER=vanessa
SSH_AUTH_SOCK=/var/run/com.apple.launchd.W09Rwm2Gsh/Listeners
PATH=/Library/Frameworks/Python.framework/Versions/3.14/bin:/Library/Frameworks/Python.framework/Versions/3.14/bin:/Library/Frameworks/Python.framework/Versions/3.13/bin:/Library/Frameworks/Python.framework/Versions/3.13/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin
__CFBundleIdentifier=com.apple.Terminal
PWD=/Users/vanessa/Desktop
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
SHLVL=1
HOME=/Users/vanessa
LOGNAME=vanessa
OSLogRateLimit=64
COLORTERM=truecolor
OLDPWD=/Users/vanessa/Desktop
HOMEBREW_PREFIX=/opt/homebrew
HOMEBREW_CELLAR=/opt/homebrew/Cellar
HOMEBREW_REPOSITORY=/opt/homebrew
FPATH=/opt/homebrew/share/zsh/site-functions:/usr/local/share/zsh/site-functions:/usr/share/zsh/site-functions:/usr/share/zsh/5.9/functions
INFOPATH=/opt/homebrew/share/info:
LANG=C.UTF-8
LC_CTYPE=UTF-8
_=/usr/bin/printenv

Creemos una variable

Comillas simples/dobles (’) (”) → Almacenar una cadena

Backquote (`) → Almacenar el contenido de lo que regrese la ejecución

Variable de ambiente

VAR_NAME=value; export VAR_NAME

vanessa@MacBook-Air-de-Vanessa Desktop % SECRET_IDENTITY='Batman'; export SECRET_IDENTITY
vanessa@MacBook-Air-de-Vanessa Desktop % echo $SECRET_IDENTITY 
Batman

Variable de sesión (expira al cerrar)

VAR_NAME=value

vanessa@MacBook-Air-de-Vanessa Desktop % MY_THIS_HOUR=`/bin/date +"%d/%b/%Y:%H"` 
vanessa@MacBook-Air-de-Vanessa Desktop % echo $MY_THIS_HOUR 
03/Jun/2026:19

Recepción de parámetros

Igual que en una función, hay ocaciones en donde necesitaremos recibir parámetros

  1. Creamos archivo → nano test.sh

    echo $0 #Nombre del archivo
    echo "Holi $1" #Primer parámetro
  2. Nos damos permiso para ejecutar → chmod 711 test.sh

  3. Ejecutamos con parámetro → ./test.sh 'Gru'

    vanessa@MacBook-Air-de-Vanessa Desktop % ./test.sh 'Gru'
    ./test.sh
    Holi Gru

Condicionales

Sintaxis general

if [ condition ]
then
    statement
else
    do this by default
fi

Ejemplo:

MY_FILE=test.sh  
if [ -f "$MY_FILE" ]; then
        echo 'YES!'
else
        echo 'Nein, 404 ):'
fi
vanessa@MacBook-Air-de-Vanessa Desktop % MY_FILE=test.sh  
if [ -f "$MY_FILE" ]; then
        echo 'YES!'
else
        echo 'Nein, 404 ):'
fi
YES!

Ciclos y Órdenes de evaluación de expresiones

Los ciclos for y while nos serán muy útiles para leer logs y poder detectar patrones. A continuación un ejemplo de cómo podemos extraer información de un archivo:

  1. Creemos un archivo de prueba → nano heroes.txt

heroes.txt

1. Spider Man - Peter Parker
2. Iron Man - Tony Stark
3. Captain America - Steve Rogers
4. Thor - Thor Odinson
5. Hulk - Bruce Banner
6. Black Widow - Natasha Romanoff
7. Wolverine - Logan
8. Doctor Strange - Stephen Strange
9. Black Panther - T'Challa
10. Captain Marvel - Carol Danvers
11. Deadpool - Wade Wilson
12. Daredevil - Matt Murdock
13. Ant Man - Scott Lang
14. Hawkeye - Clint Barton
15. Scarlet Witch - Wanda Maximoff
16. Vision - Victor Shade
17. Luke Cage - Carl Lucas
18. Mister Fantastic - Reed Richards
19. Invisible Woman - Sue Storm
20. Loki - Loki Laufeyson
  1. Leemos cada línea del archivo

awk → Utilidad de procesamiento de texto de bash

| → ‘Pipe’ (entubar) → Redirigir el contenido o output de un comando hacia otro

'{print $2}' → Imprimir sólo el segundo conjunto de elementos de la línea (campos)

while read p; do
  echo $p | awk {'print $2'}
done < heroes.txt
Spider
Iron
Captain
Thor
Hulk
Black
Wolverine
Doctor
Black
Captain
Deadpool
Daredevil
Ant
Hawkeye
Scarlet
Vision
Luke
Mister
Invisible
Loki

Supongamos que queremos encontrar sólo los registros con un cierto nombre o que contengan una cierta cadena. Empleamos la utilidad de grep para buscar patrones y devolver las coincidencias:

while read p; do
  echo $p | grep 'Man'
done < heroes.txt
1. Spider Man - Peter Parker
2. Iron Man - Tony Stark
13. Ant Man - Scott Lang

Ahora pensemos en tomar información dentro de un delimitador específico (obtener el nombre completo de nuestro super héore)

awk → Utilidad de procesamiento de texto de bash

-F'[.-]' → Tomar como separador ‘.’ y ‘-’ en lugar de espacios (delimitador)

'{print $2}' → Imprimir sólo el segundo conjunto de elementos de la línea (campos)

while read p; do
  echo $p | awk -F'[.-]' '{print $2}'
done < heroes.txt
 Spider
 Iron Man 
 Captain America 
 Thor 
 Hulk 
 Black Widow 
 Wolverine 
 Doctor Strange 
 Black Panther 
 Captain Marvel 
 Deadpool 
 Daredevil 
 Ant
 Hawkeye 
 Scarlet Witch 
 Vision 
 Luke Cage 
 Mister Fantastic 
 Invisible Woman 
 Loki 

Un ciclo for estándar

for i in {1..5}
do
   echo $i
done
1
2
3
4
5

También se pueden hacer ciclos anidados con condiciones

for i in {1..5}
do
   echo ""
   for j in {1..5}
   do
       if (( j % 2 == 0 )); then
           echo -n '■'
         else
             echo -n '□'
         fi
   done
done
□■□■□
□■□■□
□■□■□
□■□■□
□■□■□

Etiquetas relacionadas:
Arriba