Categoría: Sistemas

  • 1.3 – Estructura de archivos en Linux

    1.3 – Estructura de archivos en Linux

    Cuando empezamos a trabajar con Linux, una de las primeras cosas que debemos aprender es cómo está organizado su sistema de archivos.

    En Windows, estamos acostumbrados a trabajar con unidades como C:, D: o carpetas como “Mis documentos”. En Linux, la lógica es diferente: todo parte de una única raíz y desde ahí se organiza el resto del sistema.

    Esto hace que Linux tenga una estructura muy ordenada y bastante coherente entre distintas distribuciones.

    Aunque esta guía está basada en Ubuntu, gran parte de lo que vamos a ver también se aplica a otras distribuciones como:

    • Debian
    • Linux Mint
    • Fedora
    • Rocky Linux
    • AlmaLinux
    • Arch Linux
    • openSUSE

    Idea clave: en Linux todo cuelga de /

    En Linux, la carpeta principal de todo el sistema es:

    /

    A esto se le llama raíz del sistema.

    Desde esa carpeta nacen todas las demás.
    No existen letras de unidad como en Windows. Aunque haya varios discos o particiones, Linux los integra dentro del mismo árbol de directorios.

    Ejemplo visual

    /
    ├── bin
    ├── boot
    ├── dev
    ├── etc
    ├── home
    ├── media
    ├── mnt
    ├── opt
    ├── proc
    ├── root
    ├── run
    ├── srv
    ├── sys
    ├── tmp
    ├── usr
    └── var

    Qué debes recordar
    En Linux, todo empieza en /.
    Cualquier archivo o carpeta del sistema está dentro de esa jerarquía.


    Ubuntu y el resto de distribuciones

    Ubuntu comparte gran parte de su estructura con otras distribuciones Linux. Esto ocurre porque muchas siguen una organización tradicional común heredada del mundo Unix.

    Esto significa que:

    • si aprendes a moverte por Ubuntu, gran parte de ese conocimiento te servirá en otras distribuciones
    • las carpetas principales suelen tener la misma función
    • lo que más cambia entre distribuciones suele ser:
      • el gestor de paquetes
      • algunas herramientas
      • ciertos archivos o configuraciones concretas

    Ejemplo

    • En Ubuntu y Debian se usa mucho apt
    • En Fedora se usa dnf
    • En Arch Linux se usa pacman

    Pero carpetas como /home, /etc, /var o /usr seguirán teniendo una función muy similar.

    Importante
    La estructura general de directorios en Linux es bastante común entre distribuciones.
    Lo que cambia más es el ecosistema de herramientas, no la lógica principal del sistema de archivos.


    Directorios principales de Linux

    A continuación vamos a ver las carpetas más importantes que debe conocer un alumno cuando empieza con Linux.


    / — La raíz del sistema

    Es el nivel más alto del sistema de archivos.

    No es la carpeta del administrador, ni la carpeta del usuario.
    Es simplemente el punto de partida de toda la estructura.

    Ejemplos de rutas absolutas

    /etc/hosts
    /home/alumno
    /var/log

    Recuerda
    Cuando una ruta empieza por /, estamos hablando de una ruta absoluta.


    /home — Carpetas personales de los usuarios

    Aquí se guardan las carpetas personales de los usuarios normales del sistema.

    Ejemplos

    /home/antonio
    /home/alumno1
    /home/alumno2

    Dentro de cada carpeta de usuario suelen estar:

    • documentos
    • descargas
    • escritorio
    • configuraciones personales
    • archivos ocultos de programas

    Ejemplo práctico

    cd /home
    ls
    cd /home/alumno
    pwd

    Muy importante
    La carpeta personal del usuario suele ser su zona principal de trabajo.


    /root — Carpeta personal del administrador

    Esta carpeta pertenece al usuario root, es decir, al superusuario del sistema.

    Ojo con esto

    Muchos alumnos confunden:

    • / → raíz del sistema
    • /root → carpeta personal del administrador

    No son lo mismo.

    Error muy común
    /root no es “la raíz”.
    La raíz real del sistema es /.


    /etc — Archivos de configuración del sistema

    Aquí se encuentran muchos archivos de configuración global del sistema y de los servicios instalados.

    Ejemplos típicos

    /etc/hostname
    /etc/hosts
    /etc/passwd
    /etc/ssh/sshd_config
    /etc/apache2/

    Si instalamos servicios como SSH, Apache, MySQL o Nginx, gran parte de su configuración suele estar aquí.

    Ejemplo práctico

    cd /etc
    ls

    Qué debes aprender
    Si una configuración afecta al sistema o a todos los usuarios, es muy probable que esté en /etc.


    /usr — Programas y recursos del sistema

    Aunque por el nombre pueda parecer que significa “carpeta de usuario”, en realidad no es la carpeta personal del usuario.

    /usr contiene una gran parte de los programas, bibliotecas y recursos compartidos del sistema.

    Subdirectorios habituales

    • /usr/bin
    • /usr/sbin
    • /usr/lib
    • /usr/share

    Ejemplos

    ls /usr/bin
    ls /usr/share

    Aquí se almacenan, por ejemplo:

    • ejecutables
    • bibliotecas
    • documentación
    • iconos
    • archivos compartidos por programas

    No confundas
    /usr no sustituye a /home.
    /home es para usuarios.
    /usr es para software y recursos del sistema.


    /var — Datos variables del sistema

    La carpeta /var contiene archivos que cambian con frecuencia.

    Aquí suelen guardarse:

    • logs
    • cachés
    • colas
    • datos temporales persistentes
    • información que cambia durante el funcionamiento del sistema

    Subdirectorios frecuentes

    • /var/log
    • /var/cache
    • /var/spool
    • /var/tmp

    Ejemplo práctico

    cd /var/log
    ls

    Muy útil en administración
    Cuando algo falla, muchas veces hay que mirar en /var/log.
    Es uno de los primeros sitios donde buscar pistas.


    /tmp — Archivos temporales

    Esta carpeta se utiliza para guardar archivos temporales.

    Se usa para:

    • datos provisionales
    • archivos de trabajo
    • información temporal de programas o usuarios

    Ejemplo

    cd /tmp
    touch prueba.txt
    ls -l

    Aviso
    No conviene guardar trabajos importantes en /tmp, porque su contenido puede borrarse automáticamente.


    /boot — Archivos de arranque

    Esta carpeta contiene archivos necesarios para iniciar el sistema.

    Aquí pueden encontrarse:

    • el kernel
    • imágenes de arranque
    • archivos del gestor de arranque

    Zona delicada
    No se debe modificar esta carpeta sin saber exactamente lo que se está haciendo.


    /dev — Dispositivos

    En Linux, muchos dispositivos se representan como archivos.

    Ejemplos típicos

    /dev/sda
    /dev/sdb
    /dev/null
    /dev/tty

    Esto permite que Linux trate distintos recursos del sistema siguiendo una misma filosofía: muchas cosas se manejan como archivos.

    Idea importante
    En Linux, los dispositivos también forman parte del sistema de archivos.


    /media y /mnt — Montaje de dispositivos

    Estas rutas están relacionadas con el montaje de discos, particiones, pendrives y otros medios de almacenamiento.

    Diferencia general

    • /media suele usarse para dispositivos montados automáticamente
    • /mnt suele usarse para montajes manuales o temporales

    Ejemplo posible en Ubuntu

    /media/alumno/USB_DATOS

    Recuerda
    Cuando conectas un USB en Ubuntu, lo normal es que se monte dentro de /media.


    /proc — Información sobre procesos y sistema

    /proc no es una carpeta normal guardada en disco.
    Es un sistema de archivos virtual que muestra información del kernel y de los procesos en ejecución.

    Ejemplos

    /proc/cpuinfo
    /proc/meminfo
    /proc/1

    Comandos útiles

    cat /proc/cpuinfo
    cat /proc/meminfo

    Curiosidad interesante
    Linux permite consultar información del sistema como si fueran archivos normales.


    /sys — Información del hardware y del kernel

    Es otra ruta especial del sistema.
    También es virtual y sirve para mostrar información sobre dispositivos, hardware y estructura interna del sistema.

    No suele ser la primera carpeta que necesita dominar un principiante, pero conviene saber que existe.


    /run — Datos temporales del sistema en ejecución

    Aquí se almacenan datos generados desde el arranque del sistema.

    Por ejemplo:

    • identificadores de procesos
    • sockets
    • estados de servicios
    • información temporal de ejecución

    Es una carpeta importante en sistemas Linux modernos.


    /opt — Software adicional

    Se utiliza a menudo para instalar aplicaciones de terceros o software adicional que no forma parte del conjunto básico del sistema.

    Ejemplos

    /opt/google
    /opt/miaplicacion

    No todos los programas se instalan aquí, pero es una ruta bastante habitual en algunos casos.


    /srv — Datos de servicios

    Esta carpeta está pensada para guardar datos servidos por servicios del sistema.

    Por ejemplo:

    • contenido de un servidor web
    • archivos compartidos por un servicio FTP
    • recursos ofrecidos por un servidor

    No siempre se utiliza mucho en entornos domésticos, pero conviene conocerla.


    /bin, /sbin, /lib y /lib64

    Estas carpetas están relacionadas con:

    • comandos esenciales
    • herramientas de administración
    • bibliotecas necesarias para ejecutar programas

    En muchos sistemas modernos algunas de estas rutas están integradas o enlazadas con otras dentro de /usr, pero siguen apareciendo y es importante conocerlas.

    Idea sencilla para el alumno

    • /bin y /sbin → comandos y herramientas
    • /lib y /lib64 → bibliotecas del sistema

    Nota
    Aunque hoy existan cambios internos en muchos sistemas modernos, estas rutas siguen formando parte del mapa clásico de Linux.




    Comparación rápida con Windows

    En Windows

    • hay unidades como C: o D:
    • el usuario suele estar en C:\Users\Nombre
    • parte de la configuración está repartida entre carpetas y registro

    En Linux

    • todo cuelga de /
    • el usuario suele estar en /home/usuario
    • la configuración global suele estar en /etc
    • los logs suelen estar en /var/log

    Equivalencias mentales aproximadas

    • C:\Users\Antonio/home/antonio
    • C:\Program Files → parecido a partes de /usr o /opt
    • archivos temporales → /tmp
    • configuración del sistema → /etc

    Ojo
    No son equivalencias exactas, pero sirven para orientarse al principio.


    Diferencias entre distribuciones

    Aunque la estructura general es parecida, hay diferencias entre distribuciones.

    Ubuntu, Debian y Linux Mint

    • muy similares
    • comparten muchas rutas y herramientas
    • usan paquetes .deb y apt

    Fedora, Rocky y AlmaLinux

    • estructura también parecida
    • cambian herramientas y paquetes
    • usan dnf

    Arch Linux

    • estructura general reconocible
    • más configuración manual
    • enfoque más minimalista

    openSUSE

    • estructura general también similar
    • cambia sobre todo en herramientas de administración

    Conclusión importante
    Si aprendes bien carpetas como /home, /etc, /var, /usr y /tmp, ese conocimiento te servirá en casi cualquier distribución Linux.


    Qué carpetas debes conocer primero

    Si estás empezando, estas son las más importantes:

    • /
    • /home
    • /root
    • /etc
    • /usr
    • /var
    • /tmp
    • /dev
    • /boot
    • /media
    • /mnt

    Consejo para estudiar
    No hace falta memorizar todo el sistema de golpe.
    Lo importante es entender la función general de cada carpeta.


    Ejercicios

    1. Mostrar la carpeta actual

    pwd

    2. Entrar en la carpeta personal

    cd /home
    ls
    cd $USER
    pwd

    3. Mostrar archivos ocultos

    ls -la

    4. Explorar la configuración del sistema

    cd /etc
    ls

    5. Ver logs del sistema

    cd /var/log
    ls

    6. Consultar información del sistema

    cat /proc/cpuinfo
    cat /proc/meminfo

    7. Crear un archivo temporal

    cd /tmp
    touch practica_linux.txt
    ls -l

    8. Probar el acceso a /root

    cd /root

    Aquí el alumno verá que normalmente no tiene permisos si no es administrador.


    Errores comunes

    Confundir / con /root

    Es uno de los errores más frecuentes.

    Pensar que /usr es la carpeta del usuario

    No lo es. La carpeta del usuario normal es /home/usuario.

    Pensar que todas las carpetas son “normales”

    No. Algunas como /proc o /sys son virtuales.

    Guardar archivos importantes en /tmp

    No es buena idea.

    Creer que Ubuntu y el resto de distribuciones son totalmente diferentes

    No. Cambian cosas, pero comparten mucha base.


    Resumen

    La estructura de archivos en Linux se organiza como una jerarquía que parte de /, la raíz del sistema.
    Ubuntu sigue esta lógica igual que muchas otras distribuciones, por lo que aprender esta estructura ayuda a trabajar con soltura en casi cualquier sistema Linux.

    Las carpetas más importantes para empezar son:



    /
    ├── /home -> archivos de usuarios
    ├── /root -> carpeta del administrador
    ├── /etc -> configuración del sistema
    ├── /usr -> programas y recursos
    ├── /var -> logs y datos variables
    ├── /tmp -> archivos temporales
    ├── /boot -> arranque
    ├── /dev -> dispositivos
    ├── /proc -> información de procesos y kernel
    ├── /sys -> información del hardware
    ├── /media -> medios extraíbles
    └── /mnt -> montajes manuales

    Idea final
    Cuando entiendes la función de las carpetas, Linux deja de parecer un laberinto y empieza a parecer un sistema con sentido.

  • 1.4 – Editores de texto en Ubuntu: nano y vi

    1.4 – Editores de texto en Ubuntu: nano y vi

    Cuando trabajamos en Linux, no siempre tendremos una interfaz gráfica disponible. En muchos casos estaremos dentro de una terminal, conectados por SSH a un servidor o trabajando en una máquina sin entorno visual. En esas situaciones, saber usar un editor de texto en consola deja de ser “algo opcional” y pasa a ser una habilidad básica.

    En Ubuntu existen varios editores de texto para terminal, pero dos de los más conocidos y clásicos son:

    • nano
    • vi (o su versión mejorada, vim, en muchos sistemas)

    Aunque ambos sirven para editar archivos de texto desde la terminal, su forma de uso es muy diferente.
    Nano está pensado para ser sencillo e intuitivo.
    Vi es más potente y rápido para usuarios con experiencia, pero al principio puede parecer un pequeño artefacto caótico sacado de una nave alienígena.

    En esta guía vamos a ver qué son, para qué sirven, cómo abrir archivos, editar, guardar, salir y en qué situaciones conviene usar uno u otro.


    1. ¿Qué es un editor de texto en terminal?

    Un editor de texto en terminal es un programa que permite:

    • crear archivos de texto,
    • modificar su contenido,
    • guardar cambios,
    • editar archivos de configuración del sistema,
    • escribir scripts,
    • cambiar pequeños fragmentos de código o documentación.

    En Linux, los editores en terminal son especialmente útiles para:

    • modificar archivos de configuración en /etc,
    • editar scripts .sh,
    • crear notas rápidas,
    • trabajar en servidores remotos,
    • solucionar errores cuando no hay entorno gráfico.

    Por ejemplo, si queremos cambiar la configuración de red, revisar un archivo de Apache o editar un script de mantenimiento, es muy habitual usar un editor en consola.


    2. Editor nano

    2.1. ¿Qué es nano?

    Nano es un editor de texto en terminal sencillo, directo y fácil de aprender.
    Suele ser la mejor opción para principiantes porque muestra en pantalla los atajos principales y su funcionamiento es bastante intuitivo.

    Es muy usado para:

    • editar archivos rápidos,
    • modificar configuraciones simples,
    • crear scripts básicos,
    • trabajar en prácticas de clase sin complicarse demasiado.

    2.2. Abrir o crear un archivo con nano

    Para abrir un archivo existente o crear uno nuevo:

    nano archivo.txt

    Ejemplo:

    nano notas.txt

    Si notas.txt no existe, nano lo creará cuando lo guardemos.

    También podemos abrir archivos con ruta completa:

    nano /home/usuario/documentos/prueba.txt

    O editar archivos del sistema con permisos de administrador:

    sudo nano /etc/hosts

    2.3. Escribir y editar en nano

    Una vez dentro de nano, simplemente escribimos como si fuera un editor normal.
    No hace falta cambiar de modo ni activar nada especial.

    Podemos:

    • escribir texto directamente,
    • borrar con retroceso,
    • movernos con las flechas,
    • cortar y pegar texto con combinaciones de teclas.

    Esto lo hace muy cómodo para empezar.


    2.4. Atajos básicos de nano

    En la parte inferior de la pantalla suelen aparecer los atajos más importantes.
    El símbolo ^ significa Ctrl.

    Por ejemplo:

    • ^O significa Ctrl + O
    • ^X significa Ctrl + X

    Comandos más usados en nano

    AcciónAtajo
    Guardar archivoCtrl + O
    SalirCtrl + X
    Buscar textoCtrl + W
    Cortar líneaCtrl + K
    Pegar líneaCtrl + U
    Mostrar ayudaCtrl + G

    2.5. Guardar un archivo en nano

    Para guardar:

    Ctrl + O

    Nano pedirá confirmación del nombre del archivo.
    Pulsamos Enter para aceptar.


    2.6. Salir de nano

    Para salir:

    Ctrl + X

    Si hay cambios sin guardar, nano preguntará si queremos guardarlos.

    Opciones habituales:

    • Y → sí, guardar
    • N → no guardar

    2.7. Buscar texto en nano

    Para buscar una palabra o fragmento:

    Ctrl + W

    Escribimos el texto a buscar y pulsamos Enter.

    Esto es útil cuando editamos archivos largos de configuración.


    2.8. Ejemplo práctico con nano

    Vamos a crear un pequeño archivo de prueba:

    nano ejemplo_nano.txt

    Dentro escribimos:

    Hola, este es un archivo creado con nano.
    Estoy aprendiendo a editar desde la terminal.

    Después:

    1. Pulsamos Ctrl + O
    2. Pulsamos Enter
    3. Pulsamos Ctrl + X

    Para comprobar el contenido:

    cat ejemplo_nano.txt

    3. Editor vi

    3.1. ¿Qué es vi?

    Vi es un editor de texto clásico de Unix y Linux.
    Es muy potente, muy rápido y muy utilizado en administración de sistemas.
    El problema, para quien empieza, es que no funciona como nano ni como un editor tradicional.

    En vi existen distintos modos de trabajo. Y aquí está la trampa elegante del asunto: si no entiendes los modos, parece que el editor está roto; en realidad no está roto, solo está siendo vi.


    3.2. ¿Por qué vi puede parecer difícil?

    Porque en vi no se escribe directamente al abrir el archivo.
    Primero hay que entender que tiene varios modos.

    Los dos más importantes son:

    • modo normal: sirve para moverse, borrar, copiar, pegar, ejecutar órdenes
    • modo inserción: sirve para escribir texto

    Cuando abrimos vi, normalmente entramos en modo normal, no en modo escritura.


    3.3. Abrir o crear un archivo con vi

    vi archivo.txt

    Ejemplo:

    vi notas_vi.txt

    También podemos abrir archivos del sistema:

    sudo vi /etc/hosts

    3.4. Modos básicos de vi

    Modo normal

    Es el modo inicial.
    Aquí no escribimos texto directamente.
    Sirve para movernos por el archivo y lanzar comandos.

    Modo inserción

    Permite escribir texto.

    Para entrar en modo inserción se suele usar:

    i

    Una vez pulsamos i, ya podemos escribir.

    Para salir del modo inserción y volver al modo normal:

    Esc

    Esta tecla es importantísima. Muchísimo. Casi filosófica.


    3.5. Escribir en vi

    Pasos básicos:

    1. Abrimos el archivo: vi prueba.txt
    2. Pulsamos: i
    3. Escribimos el contenido.
    4. Pulsamos: Esc
    5. Guardamos y salimos con: :wq
    6. Pulsamos Enter

    3.6. Comandos básicos de vi

    Estos comandos se escriben en modo normal.

    AcciónComando
    Entrar en modo insercióni
    Volver a modo normalEsc
    Guardar:w
    Salir:q
    Guardar y salir:wq
    Salir sin guardar:q!
    Borrar una líneadd
    Copiar una líneayy
    Pegarp
    Buscar texto/texto

    3.7. Guardar en vi

    Para guardar el archivo:

    :w

    Y pulsamos Enter.


    3.8. Salir de vi

    Para salir si no hay cambios pendientes:

    :q

    Si queremos salir sin guardar cambios:

    :q!

    Esto es útil cuando hemos tocado algo por error y no queremos salvarlo.


    3.9. Guardar y salir en vi

    La combinación más habitual:

    :wq

    Después pulsamos Enter.


    3.10. Buscar texto en vi

    En modo normal:

    /texto

    Ejemplo:

    /ubuntu

    Esto buscará la palabra ubuntu dentro del archivo.


    3.11. Ejemplo práctico con vi

    Abrimos el archivo:

    vi ejemplo_vi.txt

    Pasos:

    1. Pulsar i
    2. Escribir:
    Este archivo ha sido creado con vi.
    Estoy aprendiendo a usar un editor modal.
    1. Pulsar Esc
    2. Escribir:
    :wq
    1. Pulsar Enter

    Para verificar:

    cat ejemplo_vi.txt

    4. Diferencias entre nano y vi

    Aunque ambos editores permiten hacer lo mismo en lo esencial, la experiencia de uso cambia bastante.

    Característicananovi
    Facilidad para principiantesMuy altaBaja al principio
    Escritura directaNo, hay que entrar en modo inserción
    Curva de aprendizajeSuaveMás pronunciada
    Rapidez para usuarios avanzadosCorrectaMuy alta
    Uso habitual en servidoresSí, muchísimo
    Ayuda visible en pantallaNo de forma tan directa
    Ideal para empezarNo especialmente
    Ideal para administración avanzadaA veces

    5. ¿Cuál conviene usar?

    Usa nano si…

    • estás empezando en Linux,
    • quieres editar archivos rápidamente,
    • no quieres aprender comandos complejos todavía,
    • necesitas algo fácil para prácticas de clase.

    Usa vi si…

    • quieres aprender herramientas clásicas de administración,
    • trabajarás en muchos servidores,
    • te interesa dominar entornos Unix/Linux de forma más profesional,
    • quieres velocidad y potencia a largo plazo.

    La recomendación más sensata para empezar suele ser:

    • primero aprender nano,
    • después conocer vi al menos a nivel básico.

    Porque tarde o temprano te lo vas a encontrar. Vi aparece en servidores, distribuciones mínimas, sistemas de recuperación y contextos donde no siempre tendrás “tu editor favorito”. Es un poco como una llave inglesa vieja: no es glamurosa, pero cuando hace falta, hace falta.



    10. Tabla resumen final

    Tareananovi
    Abrir archivonano archivo.txtvi archivo.txt
    Escribir textoDirectamentePulsar i
    GuardarCtrl + O:w
    SalirCtrl + X:q
    Guardar y salirGuardar y luego salir:wq
    Salir sin guardarResponder N al salir:q!
    Buscar textoCtrl + W/texto

    11. Ejercicios propuestos

    Ejercicio 1

    Crea un archivo llamado practica_nano.txt con nano y escribe tres líneas explicando qué es Linux.

    Ejercicio 2

    Edita el archivo anterior y añade una cuarta línea.

    Ejercicio 3

    Crea un archivo llamado practica_vi.txt con vi, escribe dos líneas y guárdalo correctamente.

    Ejercicio 4

    Abre un archivo con vi, escribe algo y sal sin guardar usando :q!.

    Ejercicio 5

    Busca una palabra dentro de un archivo usando:

    • Ctrl + W en nano
    • /texto en vi

    Conclusión

    Saber usar un editor en terminal es una competencia básica en Linux.
    Aunque hoy en día existan muchos editores gráficos y herramientas modernas, en administración de sistemas, servidores y tareas técnicas sigue siendo muy habitual editar archivos desde consola.

    Nano es la puerta de entrada ideal para empezar.
    Vi es una herramienta más exigente, pero también más potente y muy importante en el mundo Linux.

    Lo recomendable es no complicarse al principio:
    aprende primero a trabajar con nano, y después familiarízate con vi aunque solo sea en sus comandos esenciales. Con eso ya tendrás una base muy útil para seguir avanzando.


  • 1.5 – Comando find en Ubuntu

    1.5 – Comando find en Ubuntu

    El comando find es una de las herramientas más potentes de Linux para buscar archivos y directorios dentro del sistema.

    A diferencia de otros comandos más simples, find no solo permite localizar elementos por su nombre, sino también filtrarlos por muchas otras características, como por ejemplo:

    • nombre
    • tipo de archivo
    • tamaño
    • fecha de modificación
    • usuario propietario
    • permisos
    • contenido combinado con otros comandos
    • y mucho más

    Es un comando muy útil tanto para tareas cotidianas como para administración de sistemas, automatización y mantenimiento.


    ¿Para qué sirve find?

    find se utiliza para recorrer directorios y buscar elementos que cumplan unas condiciones concretas.

    Algunos usos habituales son:

    • localizar un archivo cuyo nombre no recordamos bien
    • buscar todos los archivos .txt o .log
    • encontrar carpetas concretas
    • detectar archivos grandes
    • localizar archivos modificados recientemente
    • buscar archivos vacíos
    • combinar la búsqueda con acciones automáticas, como borrar o ejecutar otro comando

    Sintaxis básica

    find [ruta] [condiciones]

    Estructura

    • ruta: lugar desde el que comienza la búsqueda
    • condiciones: filtros que debe cumplir el archivo o directorio

    Ejemplo mínimo

    find /home

    Este comando recorre todo el directorio /home y muestra todo lo que encuentra: archivos, carpetas, enlaces, etc.


    Primeros ejemplos sencillos

    Buscar en el directorio actual

    find .

    El punto . significa directorio actual.

    Buscar dentro de /home

    find /home

    Buscar un archivo por nombre exacto

    find /home -name "documento.txt"

    Busca un archivo llamado exactamente documento.txt.


    Buscar por nombre

    Opción -name

    Permite buscar por nombre respetando mayúsculas y minúsculas.

    find /home -name "foto.jpg"

    Esto encontrará solo archivos o directorios con ese nombre exacto.

    Opción -iname

    Permite buscar ignorando mayúsculas y minúsculas.

    find /home -iname "foto.jpg"

    Esto encontraría:

    • foto.jpg
    • Foto.jpg
    • FOTO.JPG

    Muy útil cuando no recordamos bien cómo estaba escrito el nombre.


    Uso de comodines

    find permite usar comodines entre comillas.

    Buscar todos los archivos .txt

    find /home -name "*.txt"

    Buscar todos los archivos .log

    find /var/log -name "*.log"

    Buscar nombres que empiecen por “tema”

    find /home -name "tema*"

    Buscar nombres que terminen en “2025”

    find /home -name "*2025"

    Buscar por tipo

    Con la opción -type podemos indicar qué queremos encontrar.

    Tipos más usados

    • f → archivo normal
    • d → directorio
    • l → enlace simbólico

    Buscar solo archivos

    find /home -type f

    Buscar solo directorios

    find /home -type d

    Buscar solo enlaces simbólicos

    find /home -type l

    Buscar archivos .pdf

    find /home -type f -name "*.pdf"

    Aquí combinamos dos condiciones:

    • que sea archivo
    • que termine en .pdf

    Buscar por tamaño

    La opción -size permite buscar por tamaño.

    Unidades comunes

    • c → bytes
    • k → kilobytes
    • M → megabytes
    • G → gigabytes

    Ejemplos

    Buscar archivos de exactamente 10 MB

    find /home -type f -size 10M

    Buscar archivos mayores de 100 MB

    find /home -type f -size +100M

    Buscar archivos menores de 1 MB

    find /home -type f -size -1M

    El signo cambia mucho la película:

    • 10M → exactamente 10 MB
    • +10M → más de 10 MB
    • -10M → menos de 10 MB

    Buscar por fecha

    find también puede buscar según el momento en que un archivo fue modificado.

    Opción -mtime

    Busca por días desde la última modificación.

    Archivos modificados hace menos de 7 días

    find /home -type f -mtime -7

    Archivos modificados hace más de 30 días

    find /home -type f -mtime +30

    Archivos modificados exactamente hace 1 día

    find /home -type f -mtime 1

    Opción -mmin

    Busca por minutos desde la última modificación.

    Archivos modificados en los últimos 60 minutos

    find /home -type f -mmin -60

    Esto es muy útil para tareas recientes o diagnósticos.


    Buscar por usuario o grupo

    Buscar archivos de un usuario concreto

    find /home -user alumno1

    Buscar archivos de un grupo concreto

    find /home -group profesores

    Esto puede venir muy bien en sistemas multiusuario.


    Buscar por permisos

    La opción -perm permite localizar archivos con permisos específicos.

    Buscar archivos con permiso 644

    find /home -type f -perm 644

    Buscar directorios con permiso 755

    find /home -type d -perm 755

    Esto es útil para revisar seguridad, configuraciones o errores de permisos.


    Buscar archivos vacíos

    Archivos vacíos

    find /home -type f -empty

    Directorios vacíos

    find /home -type d -empty

    Muy útil para limpieza del sistema o revisión de estructuras.


    Limitar la profundidad de búsqueda

    A veces no queremos que find recorra infinitamente subcarpetas como si estuviera poseído por un espíritu del caos. Para eso usamos estas opciones.

    -maxdepth

    Limita cuántos niveles de profundidad puede bajar.

    find /home -maxdepth 1

    Muestra solo lo que hay en /home sin entrar en subdirectorios.

    -mindepth

    Indica desde qué nivel empezar a mostrar resultados.

    find /home -mindepth 1

    Evita mostrar el directorio inicial.

    Ejemplo combinado

    find /home -mindepth 1 -maxdepth 2 -type f

    Busca archivos desde el primer nivel hasta el segundo.


    Ejecutar acciones con los resultados

    Una de las funciones más potentes de find es usar -exec, que permite ejecutar comandos sobre cada resultado encontrado.

    Sintaxis

    find [ruta] [condición] -exec comando {} \;
    • {} representa el archivo encontrado
    • \; indica el final del comando

    Ejemplo: mostrar información detallada

    find /home -name "*.txt" -exec ls -l {} \;

    Ejemplo: borrar archivos

    find /home -type f -name "*.tmp" -exec rm {} \;

    Cuidado con esto. Aquí ya estamos jugando con fuego elegante.

    Ejemplo: cambiar permisos

    find /home/proyecto -type f -name "*.sh" -exec chmod +x {} \;

    Borrar directamente con -delete

    También se puede borrar sin usar -exec.

    find /home -type f -name "*.tmp" -delete

    Esto es muy útil, pero también peligroso si no hemos probado antes la búsqueda.

    Recomendación importante

    Primero ejecuta la búsqueda sin borrar:

    find /home -type f -name "*.tmp"

    Y cuando compruebes que el resultado es correcto, entonces usas:

    find /home -type f -name "*.tmp" -delete

    Combinar varias condiciones

    find permite combinar condiciones para hacer búsquedas mucho más precisas.

    Buscar archivos .log de más de 10 MB

    find /var/log -type f -name "*.log" -size +10M

    Buscar archivos .txt modificados en los últimos 2 días

    find /home -type f -name "*.txt" -mtime -2

    Buscar directorios vacíos

    find /home -type d -empty

    Uso de operadores lógicos

    Opción -o (OR)

    Busca una cosa o la otra.

    find /home -name "*.jpg" -o -name "*.png"

    Busca archivos .jpg o .png.

    Opción ! (NOT)

    Niega una condición.

    find /home -type f ! -name "*.txt"

    Busca archivos que no terminen en .txt.


    Ejemplos prácticos

    1. Buscar todos los archivos PDF de un usuario

    find /home/alumno -type f -name "*.pdf"

    2. Buscar carpetas llamadas backup

    find /home -type d -name "backup"

    3. Buscar archivos grandes en todo el sistema

    find / -type f -size +500M

    4. Buscar archivos modificados hoy aproximadamente

    find /home -type f -mtime -1

    5. Buscar archivos temporales y eliminarlos

    find /tmp -type f -name "*.tmp" -delete

    6. Buscar scripts de shell

    find /home -type f -name "*.sh"

    7. Buscar directorios vacíos dentro del proyecto

    find /home/proyecto -type d -empty

    Buenas prácticas al usar find

    1. Empezar por una ruta concreta

    No uses / si no hace falta. Buscar desde la raíz puede tardar bastante y además mostrar errores por falta de permisos.

    Mejor algo como:

    find /home/usuario/documentos -name "*.txt"

    2. Probar primero antes de borrar

    Antes de usar -delete o -exec rm, ejecuta la búsqueda sin borrar nada.

    3. Usar comillas en los patrones

    Correcto:

    find /home -name "*.txt"

    No recomendable:

    find /home -name *.txt

    Sin comillas, el shell puede interpretar el patrón antes que find, y ahí empiezan los disgustos.

    4. Combinar condiciones para ser más preciso

    Cuanto más concreta sea la búsqueda, menos resultados basura tendrás.


    Errores comunes

    Error 1: olvidar la ruta

    find -name "*.txt"

    Aunque puede funcionar en algunos casos desde el directorio actual, es mejor escribirlo claramente:

    find . -name "*.txt"

    Error 2: no poner comillas

    find /home -name *.txt

    Puede dar resultados inesperados.

    Error 3: usar -delete sin comprobar antes

    Esto puede eliminar archivos importantes. Linux no te va a mirar con pena. Simplemente lo hará.

    Error 4: confundir -name con contenido del archivo

    find busca por nombre, tamaño, fechas, tipo, etc., pero no busca texto dentro de archivos.
    Para buscar texto dentro de archivos se usa normalmente grep.

    Ejemplo combinado:

    find /home -type f -name "*.txt" -exec grep "error" {} \;

    Opciones principales de find

    OpciónSignificadoEjemplo
    .Directorio actualfind .
    -nameBusca por nombre exacto respetando mayúsculasfind /home -name "foto.jpg"
    -inameBusca por nombre ignorando mayúsculasfind /home -iname "foto.jpg"
    -type fSolo archivosfind /home -type f
    -type dSolo directoriosfind /home -type d
    -type lSolo enlaces simbólicosfind /home -type l
    -sizeBusca por tamañofind /home -size +100M
    -mtimeBusca por días desde modificaciónfind /home -mtime -7
    -mminBusca por minutos desde modificaciónfind /home -mmin -60
    -userBusca por usuario propietariofind /home -user alumno1
    -groupBusca por grupo propietariofind /home -group profesores
    -permBusca por permisosfind /home -perm 644
    -emptyBusca archivos o directorios vacíosfind /home -empty
    -maxdepthLimita profundidad máximafind /home -maxdepth 2
    -mindepthLimita profundidad mínimafind /home -mindepth 1
    -execEjecuta un comando sobre cada resultadofind /home -name "*.txt" -exec ls -l {} \;
    -deleteBorra directamente los resultadosfind /tmp -name "*.tmp" -delete
    -oOperador ORfind /home -name "*.jpg" -o -name "*.png"
    !Negaciónfind /home ! -name "*.txt"


    Ejercicios

    Ejercicio 1

    Busca todos los archivos .txt dentro de tu carpeta personal.

    Ejercicio 2

    Busca todos los directorios dentro de /home.

    Ejercicio 3

    Encuentra archivos mayores de 50 MB.

    Ejercicio 4

    Busca archivos modificados en los últimos 3 días.

    Ejercicio 5

    Busca archivos vacíos dentro de una carpeta de pruebas.

    Ejercicio 6

    Busca todos los archivos .log y muestra solo los que sean archivos normales.

    Ejercicio 7

    Busca archivos .tmp dentro de una carpeta temporal y elimínalos solo después de comprobar el resultado.



    Soluciones

    EjercicioComando
    1find /home/$USER -type f -name "*.txt"
    2find /home -type d
    3find /home -type f -size +50M
    4find /home -type f -mtime -3
    5find /home/$USER/pruebas -type f -empty
    6find /home -type f -name "*.log"
    7find /tmp -type f -name "*.tmp" y después find /tmp -type f -name "*.tmp" -delete
  • 1.6 – Comando grep en Ubuntu

    1.6 – Comando grep en Ubuntu

    grep sirve para filtrar texto y mostrar solo las líneas que coinciden con un patrón.

    Por ejemplo, permite:

    • buscar una palabra dentro de un archivo
    • localizar errores en logs
    • encontrar líneas que contengan una IP, usuario o ruta
    • buscar texto ignorando mayúsculas
    • contar coincidencias
    • mostrar números de línea
    • buscar en varios archivos a la vez
    • combinarse con otros comandos mediante tuberías (|)

    Sintaxis básica

    grep [opciones] "patrón" archivo

    Estructura

    • opciones: modifican el comportamiento del comando
    • patrón: texto o expresión que queremos buscar
    • archivo: fichero o ficheros donde se realizará la búsqueda

    Primer ejemplo

    Supongamos que tenemos un archivo llamado notas.txt.

    Ana
    Pedro
    Lucía
    Pedro García
    María

    Si ejecutamos:

    grep "Pedro" notas.txt

    El resultado será:

    Pedro
    Pedro García

    Porque grep muestra las líneas donde aparece la palabra Pedro.


    Búsqueda básica en archivos

    Buscar una palabra en un archivo

    grep "error" sistema.log

    Muestra todas las líneas del archivo sistema.log que contienen la palabra error.

    Buscar en varios archivos a la vez

    grep "usuario" archivo1.txt archivo2.txt archivo3.txt

    Busca la palabra usuario en varios archivos.


    Ignorar mayúsculas y minúsculas

    Opción -i

    Permite buscar sin diferenciar entre mayúsculas y minúsculas.

    grep -i "ubuntu" documento.txt

    Esto encontraría:

    • ubuntu
    • Ubuntu
    • UBUNTU

    Muy útil cuando no sabemos cómo está escrito exactamente el texto.


    Mostrar números de línea

    Opción -n

    Muestra el número de línea donde aparece la coincidencia.

    grep -n "error" sistema.log

    Ejemplo de salida:

    15:error de conexión
    28:error al iniciar servicio

    Esto facilita localizar rápidamente la línea en el archivo.


    Contar coincidencias

    Opción -c

    Cuenta cuántas líneas contienen el patrón.

    grep -c "warning" sistema.log

    Devuelve un número, por ejemplo:

    7

    Esto significa que hay 7 líneas con la palabra warning.


    Mostrar solo nombres de archivos

    Opción -l

    Muestra solo los nombres de los archivos donde aparece el patrón.

    grep -l "mysql" *.txt

    En vez de mostrar las líneas, muestra qué archivos contienen esa palabra.

    Opción -L

    Hace lo contrario: muestra los archivos donde no aparece el patrón.

    grep -L "mysql" *.txt

    Buscar palabras exactas

    Opción -w

    Busca coincidencias de palabra completa.

    grep -w "sol" texto.txt

    Esto evita que aparezcan coincidencias como:

    • solitario
    • solución

    y muestra solo la palabra sol como término independiente.


    Invertir la búsqueda

    Opción -v

    Muestra las líneas que no coinciden con el patrón.

    grep -v "admin" usuarios.txt

    Muy útil para excluir líneas.


    Buscar recursivamente en carpetas

    Opción -r

    Busca dentro de todos los archivos de un directorio y sus subdirectorios.

    grep -r "localhost" /etc

    Busca la palabra localhost en todos los archivos dentro de /etc.

    Opción -rn

    Muy usada para búsqueda recursiva con número de línea.

    grep -rn "puerto" /etc

    Mostrar coincidencias exactas dentro de una línea

    Opción -o

    Muestra solo la parte de la línea que coincide.

    grep -o "error" sistema.log

    Si una línea tiene varias veces la palabra error, puede mostrar cada coincidencia por separado.


    Expresiones regulares básicas

    grep puede trabajar con patrones más avanzados mediante expresiones regulares.

    Buscar líneas que empiecen por una palabra

    grep "^root" usuarios.txt

    El símbolo ^ indica inicio de línea.

    Buscar líneas que terminen con una palabra

    grep "bash$" usuarios.txt

    El símbolo $ indica final de línea.

    Buscar líneas que contengan números

    grep "[0-9]" datos.txt

    Esto busca cualquier línea que contenga al menos un dígito.

    Buscar vocales

    grep "[aeiou]" texto.txt

    Buscar letras mayúsculas

    grep "[A-Z]" texto.txt

    Aquí empieza la magia útil. Con moderación, porque las expresiones regulares también tienen fama de convertirse en jeroglíficos con malas pulgas.


    Uso con tuberías

    Una de las cosas más potentes de grep es usarlo junto con otros comandos.

    Buscar un proceso en ejecución

    ps aux | grep apache

    Muestra las líneas del listado de procesos donde aparece apache.

    Buscar un servicio activo

    systemctl list-units | grep ssh

    Filtrar resultados de un listado

    ls -l | grep ".txt"

    Aquí grep filtra la salida de otro comando.


    Buscar en logs

    grep se usa muchísimo para revisar logs.

    Buscar errores en un archivo de log

    grep -i "error" /var/log/syslog

    Buscar intentos fallidos

    grep -i "failed" /var/log/auth.log

    Buscar accesos SSH

    grep "sshd" /var/log/auth.log

    Esto es especialmente útil en administración y ciberseguridad.


    Usar grep con find

    Una combinación muy habitual es usar find para localizar archivos y grep para buscar texto dentro de ellos.

    Buscar la palabra “password” en archivos .conf

    find /etc -name "*.conf" -exec grep -H "password" {} \;

    Explicación

    • find localiza archivos .conf
    • grep busca la palabra password
    • -H hace que aparezca también el nombre del archivo

    Mostrar nombre del archivo junto al resultado

    Opción -H

    grep -H "localhost" /etc/hosts

    Si se buscan varios archivos, esto ayuda a saber de cuál sale cada coincidencia.


    Ocultar nombre del archivo

    Opción -h

    grep -h "usuario" archivo1.txt archivo2.txt

    Muestra solo las líneas encontradas, sin el nombre del archivo.


    Buscar coincidencias exactas con expresiones ampliadas

    Opción -E

    Activa expresiones regulares extendidas.

    grep -E "error|failed|warning" sistema.log

    Busca líneas que contengan cualquiera de esas palabras.

    Muy útil porque evita tener que hacer búsquedas separadas.


    Buscar coincidencias fijas sin interpretar regex

    Opción -F

    Busca texto literal, sin interpretar caracteres especiales como expresiones regulares.

    grep -F "a+b" formulas.txt

    Esto busca exactamente a+b.


    Resaltar coincidencias

    En muchas terminales, grep resalta las coincidencias automáticamente. También se puede forzar:

    grep --color=auto "error" sistema.log

    Esto mejora mucho la lectura.


    Ejemplos

    1. Buscar la palabra linux en un archivo

    grep "linux" apuntes.txt

    2. Buscar la palabra linux ignorando mayúsculas

    grep -i "linux" apuntes.txt

    3. Mostrar las líneas donde aparece admin con su número

    grep -n "admin" usuarios.txt

    4. Contar cuántas líneas contienen error

    grep -c "error" sistema.log

    5. Mostrar líneas que no contienen root

    grep -v "root" usuarios.txt

    6. Buscar recursivamente la palabra puerto en una carpeta

    grep -r "puerto" /etc

    7. Buscar varias palabras con una sola orden

    grep -E "error|warning|failed" sistema.log

    8. Buscar procesos relacionados con mysql

    ps aux | grep mysql

    Buenas prácticas al usar grep

    1. Usar comillas en el patrón

    Correcto:

    grep "error de red" log.txt

    Esto evita que el shell haga cosas raras con espacios o caracteres especiales.

    2. Usar -i cuando no importe cómo está escrito

    Si buscas nombres, usuarios o palabras que pueden ir en mayúsculas o minúsculas, ahorra disgustos.

    3. Usar -n para localizar mejor

    Muy recomendable cuando luego se va a editar el archivo.

    4. Probar primero búsquedas simples

    Antes de montar una expresión regular digna de un grimorio arcano, comprueba que el texto base aparece.

    5. Tener cuidado con búsquedas recursivas en rutas grandes

    Buscar en / o en directorios enormes puede tardar bastante y generar mucho ruido.


    Errores comunes

    Error 1: pensar que grep busca archivos por nombre

    No.
    grep busca texto dentro de archivos o dentro de la salida de comandos.

    Para buscar archivos por nombre se usa find.

    Error 2: olvidar las comillas

    grep error de red log.txt

    Esto no se interpreta como una sola búsqueda, sino como varios argumentos.

    Lo correcto sería:

    grep "error de red" log.txt

    Error 3: confundir coincidencia parcial con palabra exacta

    grep "sol" texto.txt

    Puede encontrar:

    • sol
    • solución
    • solitario

    Si queremos solo la palabra completa:

    grep -w "sol" texto.txt

    Error 4: usar expresiones regulares sin darse cuenta

    Caracteres como ., *, ^, $, [ ] tienen significado especial.
    Si quieres buscar texto literal con símbolos, a veces conviene usar -F.


    Opciones principales de grep

    OpciónSignificadoEjemplo
    -iIgnora mayúsculas y minúsculasgrep -i "ubuntu" archivo.txt
    -nMuestra número de líneagrep -n "error" log.txt
    -cCuenta líneas coincidentesgrep -c "warning" log.txt
    -lMuestra solo nombres de archivos con coincidenciagrep -l "mysql" *.txt
    -LMuestra archivos sin coincidenciagrep -L "mysql" *.txt
    -wBusca palabra exactagrep -w "sol" texto.txt
    -vInvierte la búsquedagrep -v "admin" usuarios.txt
    -rBusca recursivamente en carpetasgrep -r "localhost" /etc
    -rnRecursivo con número de líneagrep -rn "puerto" /etc
    -oMuestra solo la coincidenciagrep -o "error" log.txt
    -HMuestra nombre del archivogrep -H "root" archivo.txt
    -hOculta nombre del archivogrep -h "root" archivo1.txt archivo2.txt
    -EUsa expresiones regulares extendidas`grep -E «error
    -FBusca texto literalgrep -F "a+b" archivo.txt
    --color=autoResalta coincidenciasgrep --color=auto "error" log.txt

    Diferencia entre grep y find

    Esto conviene dejarlo muy claro a los alumnos, porque se confunden muchísimo al principio.

    Comando¿Qué busca?Ejemplo
    findArchivos y directorios por nombre, tipo, tamaño, fecha, etc.find /home -name "*.txt"
    grepTexto dentro de archivos o salida de comandosgrep "error" log.txt

    Ejemplo práctico

    • find responde a: “¿Dónde están los archivos .txt?”
    • grep responde a: “¿Qué archivos contienen la palabra error?”

    Uno busca cosas.
    El otro busca texto dentro de las cosas.
    Cada uno hace su hechicería.


    Ejercicios

    Ejercicio 1

    Busca la palabra linux dentro de un archivo llamado apuntes.txt.

    Ejercicio 2

    Busca la palabra ubuntu ignorando mayúsculas y minúsculas.

    Ejercicio 3

    Muestra en qué líneas aparece la palabra admin dentro de usuarios.txt.

    Ejercicio 4

    Cuenta cuántas líneas contienen la palabra error en sistema.log.

    Ejercicio 5

    Muestra todas las líneas que no contienen la palabra root.

    Ejercicio 6

    Busca recursivamente la palabra servidor dentro de la carpeta /etc.

    Ejercicio 7

    Busca cualquiera de estas palabras en sistema.log: error, warning o failed.

    Ejercicio 8

    Muestra los procesos en ejecución relacionados con ssh.


    Soluciones de los ejercicios

    Ejercicio 1

    Enunciado: Busca la palabra linux dentro de un archivo llamado apuntes.txt.

    grep "linux" apuntes.txt

    Busca las líneas del archivo apuntes.txt que contienen la palabra linux.


    Ejercicio 2

    Enunciado: Busca la palabra ubuntu ignorando mayúsculas y minúsculas.

    grep -i "ubuntu" apuntes.txt

    La opción -i permite encontrar ubuntu, Ubuntu, UBUNTU, etc.


    Ejercicio 3

    Enunciado: Muestra en qué líneas aparece la palabra admin dentro de usuarios.txt.

    grep -n "admin" usuarios.txt

    La opción -n añade el número de línea a cada coincidencia.


    Ejercicio 4

    Enunciado: Cuenta cuántas líneas contienen la palabra error en sistema.log.

    grep -c "error" sistema.log

    La opción -c cuenta el número de líneas coincidentes.


    Ejercicio 5

    Enunciado: Muestra todas las líneas que no contienen la palabra root.

    grep -v "root" usuarios.txt

    La opción -v invierte la búsqueda y muestra las líneas que no contienen ese patrón.


    Ejercicio 6

    Enunciado: Busca recursivamente la palabra servidor dentro de la carpeta /etc.

    grep -r "servidor" /etc

    La opción -r busca en todos los archivos dentro del directorio y sus subdirectorios.


    Ejercicio 7

    Enunciado: Busca cualquiera de estas palabras en sistema.log: error, warning o failed.

    grep -E "error|warning|failed" sistema.log

    La opción -E permite usar expresiones regulares extendidas y el operador | significa “o”.


    Ejercicio 8

    Enunciado: Muestra los procesos en ejecución relacionados con ssh.

    ps aux | grep ssh

    ps aux lista los procesos y grep ssh filtra los que contienen ssh.

  • 1.7 – Uso combinado de grep y find

    1.7 – Uso combinado de grep y find

    Los comandos find y grep son muy potentes por separado, pero cuando se combinan permiten hacer búsquedas mucho más completas.

    Recordatorio rápido

    • find sirve para buscar archivos y directorios
    • grep sirve para buscar texto dentro de archivos

    Cuando los usamos juntos, podemos hacer cosas como:

    • localizar archivos de un tipo concreto y buscar texto dentro de ellos
    • encontrar configuraciones específicas en muchos archivos
    • revisar proyectos completos
    • analizar logs
    • buscar palabras sensibles dentro de archivos de configuración
    • localizar cadenas de texto en estructuras grandes de carpetas

    ¿Por qué combinarlos?

    Porque muchas veces no basta con saber dónde está un archivo ni basta con saber qué texto contiene un archivo concreto.

    Lo que realmente queremos es algo como esto:

    • “Busca todos los archivos .txt y dime cuáles contienen la palabra error
    • “Encuentra todos los .conf y mira si aparece password
    • “Busca dentro de todos los scripts .sh cuáles usan sudo
    • “Revisa todos los archivos PHP y encuentra dónde se usa mysqli

    Ahí es donde find localiza los archivos y grep inspecciona su contenido.


    Forma más común de combinarlos

    La combinación más habitual se hace con -exec.

    Sintaxis general

    find [ruta] [condición de archivos] -exec grep [opciones] "patrón" {} \;
    • find localiza los archivos
    • grep se ejecuta sobre cada archivo encontrado
    • {} representa el archivo actual
    • \; indica el final del comando que ejecuta find

    Primer ejemplo básico

    Buscar la palabra error en todos los archivos .log

    find /var/log -type f -name "*.log" -exec grep "error" {} \;

    ¿Qué hace este comando?

    • busca en /var/log
    • solo archivos normales (-type f)
    • cuyo nombre termine en .log
    • y en cada uno ejecuta grep "error"

    Mostrar también el nombre del archivo

    En muchos casos conviene usar grep -H para que aparezca el nombre del fichero junto al resultado.

    find /var/log -type f -name "*.log" -exec grep -H "error" {} \;

    Así no solo vemos la línea encontrada, sino también en qué archivo aparece.


    Ejemplos prácticos de find + grep

    1. Buscar la palabra password en archivos .conf

    find /etc -type f -name "*.conf" -exec grep -H "password" {} \;

    Uso típico

    Revisar configuraciones donde se haya escrito la palabra password.


    2. Buscar localhost en archivos .conf

    find /etc -type f -name "*.conf" -exec grep -H "localhost" {} \;

    Uso típico

    Buscar configuraciones locales o referencias a servicios en la propia máquina.


    3. Buscar la palabra sudo en scripts .sh

    find /home/$USER -type f -name "*.sh" -exec grep -H "sudo" {} \;

    Uso típico

    Detectar scripts que usan privilegios elevados.


    4. Buscar mysqli en archivos PHP

    find /var/www/html -type f -name "*.php" -exec grep -H "mysqli" {} \;

    Uso típico

    Encontrar dónde se está usando esa librería o función en un proyecto web.


    5. Buscar líneas con import en archivos Python

    find /home/$USER/proyecto -type f -name "*.py" -exec grep -H "import" {} \;

    Uso típico

    Revisar módulos importados dentro de un proyecto Python.


    6. Buscar la palabra TODO en archivos de código

    find /home/$USER/proyecto -type f -name "*.js" -exec grep -H "TODO" {} \;

    También podríamos ampliar a varios tipos de archivo por separado.

    Por ejemplo para Java:

    find /home/$USER/proyecto -type f -name "*.java" -exec grep -H "TODO" {} \;

    Uso típico

    Localizar tareas pendientes dejadas por el programador.


    7. Buscar root dentro de archivos .txt

    find /home/$USER -type f -name "*.txt" -exec grep -H "root" {} \;

    Uso típico

    Revisar documentación, apuntes o ficheros exportados.


    8. Buscar líneas que contengan error ignorando mayúsculas

    find /var/log -type f -name "*.log" -exec grep -Hi "error" {} \;
    • -H muestra el nombre del archivo
    • -i ignora mayúsculas y minúsculas

    Esto encontraría error, Error, ERROR, etc.


    9. Buscar coincidencias con número de línea

    find /etc -type f -name "*.conf" -exec grep -Hn "Listen" {} \;
    • -H muestra el archivo
    • -n muestra el número de línea

    Muy útil para editar luego el archivo correcto.


    10. Buscar palabras exactas dentro de archivos localizados por find

    find /home/$USER -type f -name "*.txt" -exec grep -Hw "linux" {} \;

    La opción -w hace que grep busque la palabra exacta linux, no partes de otras palabras.

    Usar find + grep con borrado o acciones posteriores

    A veces queremos localizar archivos cuyo contenido cumpla una condición y luego actuar sobre ellos. Aquí hay que ir con mucho cuidado, porque el pingüino no perdona los comandos mal puestos.

    Ejemplo: buscar scripts que contienen rm

    find /home/$USER/scripts -type f -name "*.sh" -exec grep -H "rm" {} \;

    Antes de ejecutar un script o revisarlo, puede interesar detectar si contiene órdenes de borrado.


    Alternativa con xargs

    También se puede combinar find con grep usando xargs.

    Ejemplo

    find /etc -type f -name "*.conf" | xargs grep -H "localhost"

    ¿Qué ocurre aquí?

    • find genera una lista de archivos
    • xargs se la pasa a grep

    Ventaja

    Puede resultar más rápido o más cómodo en algunos casos.

    Inconveniente

    Puede dar problemas si los nombres de archivos tienen espacios o caracteres raros.

    Por eso, en documentación básica para alumnos, suele ser más seguro enseñar primero -exec.


    Variante segura con espacios en nombres

    Si más adelante quieres mostrar una versión más robusta:

    find /etc -type f -name "*.conf" -print0 | xargs -0 grep -H "localhost"
    • -print0 separa resultados con carácter nulo
    • xargs -0 los interpreta correctamente

    Esto evita errores con nombres de archivo que contienen espacios.


    Diferencia entre usar solo grep -r y usar find + grep

    Esto conviene explicarlo porque los alumnos pueden pensar:
    “¿Para qué combinar nada si grep ya busca en carpetas?”

    La respuesta es: depende del control que quieras tener.

    Con grep -r

    grep -r "localhost" /etc

    Busca recursivamente en todos los archivos del directorio.

    Con find + grep

    find /etc -type f -name "*.conf" -exec grep -H "localhost" {} \;

    Busca solo en archivos .conf.

    Conclusión

    • grep -r es más rápido de escribir
    • find + grep da un control mucho más preciso sobre qué archivos analizar

    Casos reales donde se usan juntos

    1. Administración de sistemas

    Buscar una directiva concreta en archivos de configuración:

    find /etc -type f -name "*.conf" -exec grep -Hn "ServerName" {} \;

    2. Desarrollo web

    Buscar credenciales hardcodeadas o funciones concretas:

    find /var/www/html -type f -name "*.php" -exec grep -Hn "password" {} \;

    3. Python

    Buscar imports concretos:

    find /home/$USER/proyecto -type f -name "*.py" -exec grep -Hn "requests" {} \;

    4. Shell scripting

    Localizar scripts que usan curl:

    find /home/$USER/scripts -type f -name "*.sh" -exec grep -Hn "curl" {} \;

    5. Revisión de logs

    Buscar palabras clave en logs concretos:

    find /var/log -type f -name "*.log" -exec grep -Hi "failed" {} \;

    Resumen: find + grep

    ObjetivoComando
    Buscar error en .logfind /var/log -type f -name "*.log" -exec grep -H "error" {} \;
    Buscar password en .conffind /etc -type f -name "*.conf" -exec grep -H "password" {} \;
    Buscar sudo en scripts .shfind /home/$USER -type f -name "*.sh" -exec grep -H "sudo" {} \;
    Buscar mysqli en .phpfind /var/www/html -type f -name "*.php" -exec grep -H "mysqli" {} \;
    Buscar import en .pyfind /home/$USER/proyecto -type f -name "*.py" -exec grep -H "import" {} \;
    Buscar error ignorando mayúsculasfind /var/log -type f -name "*.log" -exec grep -Hi "error" {} \;
    Buscar coincidencia con número de líneafind /etc -type f -name "*.conf" -exec grep -Hn "Listen" {} \;
    Buscar palabra exacta linux en .txtfind /home/$USER -type f -name "*.txt" -exec grep -Hw "linux" {} \;

    Recomendaciones

    1. Empieza probando find solo

    Antes de combinar, comprueba qué archivos se están seleccionando.

    find /etc -type f -name "*.conf"

    2. Después añade grep

    Cuando veas que los archivos son los correctos, añades la búsqueda de texto.

    3. Usa -H casi siempre

    Así sabrás en qué archivo aparece cada coincidencia.

    4. Usa -n cuando quieras editar luego

    Te ahorra tiempo porque muestra la línea exacta.

    5. No busques a ciegas en /

    Buscar desde la raíz puede generar muchísimo ruido y errores de permisos.


    Ejercicios propuestos: combinar find y grep

    Ejercicio 1

    Busca la palabra import dentro de todos los archivos .py de una carpeta llamada proyecto.

    Ejercicio 2

    Busca la palabra error dentro de todos los archivos .log de /var/log.

    Ejercicio 3

    Busca la palabra localhost dentro de todos los archivos .conf de /etc.

    Ejercicio 4

    Busca la palabra sudo dentro de todos los scripts .sh de tu carpeta personal.

    Ejercicio 5

    Busca la palabra linux como palabra exacta dentro de todos los archivos .txt de tu carpeta personal.


    Soluciones de los ejercicios

    Ejercicio 1

    find /home/$USER/proyecto -type f -name "*.py" -exec grep -H "import" {} \;

    Ejercicio 2

    find /var/log -type f -name "*.log" -exec grep -H "error" {} \;

    Ejercicio 3

    find /etc -type f -name "*.conf" -exec grep -H "localhost" {} \;

    Ejercicio 4

    find /home/$USER -type f -name "*.sh" -exec grep -H "sudo" {} \;

    Ejercicio 5

    find /home/$USER -type f -name "*.txt" -exec grep -Hw "linux" {} \;
  • 1.8 – Cómo usar echo, >, tee

    1.8 – Cómo usar echo, >, tee

    Este comando:

    echo "Ruta secreta al sector Omega" | sudo tee /srv/andromeda/pilotos/ruta_estelar.txt

    sirve para escribir un texto dentro de un archivo con permisos de administrador.

    Explicación por partes

    1. echo "Ruta secreta al sector Omega"

    El comando echo muestra un texto por pantalla.

    En este caso, genera esta salida:

    Ruta secreta al sector Omega

    2. |

    La barra vertical se llama pipe.

    Sirve para enviar la salida de un comando al siguiente.

    Aquí lo que hace es mandar el texto generado por echo al comando tee.


    3. sudo tee /srv/andromeda/pilotos/ruta_estelar.txt

    El comando tee recoge lo que le llega por la entrada estándar y lo:

    • muestra por pantalla,
    • y además lo guarda en un archivo.

    Como va precedido de sudo, tee se ejecuta con permisos de administrador, por lo que puede escribir en una ruta protegida.

    En este caso, escribe el texto en:

    /srv/andromeda/pilotos/ruta_estelar.txt

    Qué hace en conjunto

    El comando completo:

    1. genera el texto "Ruta secreta al sector Omega",
    2. lo envía a tee,
    3. tee lo escribe dentro del archivo indicado,
    4. y además lo muestra en pantalla.

    Resultado

    El archivo ruta_estelar.txt quedará con este contenido:

    Ruta secreta al sector Omega

    ¿Por qué no usar directamente >?

    Podrías pensar en hacer:

    sudo echo "Ruta secreta al sector Omega" > /srv/andromeda/pilotos/ruta_estelar.txt

    Pero eso no funciona como se espera en muchos casos.

    La razón es que:

    • sudo se aplica a echo,
    • pero la redirección > la intenta hacer el usuario actual,
    • y ese usuario quizá no tiene permisos para escribir en esa carpeta.

    Por eso tee es muy útil: porque quien escribe realmente en el archivo es tee, y como lleva sudo, sí tiene permisos.


    Diferencia entre crear y añadir contenido

    Sobrescribir el archivo

    echo "Texto nuevo" | sudo tee archivo.txt

    Esto reemplaza el contenido anterior.

    Añadir al final del archivo

    echo "Otra línea" | sudo tee -a archivo.txt

    La opción -a significa append, es decir, añadir al final sin borrar lo que ya había.


    Ejemplo

    Crear el archivo con una línea

    echo "Primera línea" | sudo tee /tmp/prueba.txt

    Añadir otra línea

    echo "Segunda línea" | sudo tee -a /tmp/prueba.txt

    Ver el contenido

    cat /tmp/prueba.txt

    Salida:

    Primera línea
    Segunda línea

    Resumen

    ParteFunción
    echo "texto"genera un texto
    ``
    tee archivomuestra el texto y lo guarda en un archivo
    sudo tee archivoguarda el texto en un archivo con permisos de administrador
  • Instalación y Primeros Pasos con Docker en Windows

    Instalación y Primeros Pasos con Docker en Windows

    Hay conceptos que, una vez se ven, el cerebro hace clic y ya no vuelve atrás. La diferencia entre máquinas virtuales y contenedores es uno de esos momentos fundacionales en la vida de cualquier persona que empieza a pensar como ingeniero de sistemas.

    La metáfora clásica —y sorprendentemente precisa— es esta:

    👉 Las máquinas virtuales son casas completas.
    👉 Los contenedores son apartamentos dentro del mismo edificio.

    La diferencia que cambia la forma de diseñar sistemas

    Esto es lo verdaderamente importante —y lo que merece que tus alumnos lo entiendan bien:

    Con VMs piensas en:

    «Voy a crear servidores.»

    Con contenedores empiezas a pensar:

    «Voy a desplegar servicios.»

    Instalación de Docker Desktop y Portainer en Windows

    En los entornos tecnológicos actuales, la virtualización ligera mediante contenedores se ha convertido en un estándar para el desarrollo, despliegue y administración de aplicaciones.

    Docker es una plataforma que permite empaquetar aplicaciones junto con todas sus dependencias dentro de contenedores, garantizando que funcionen de forma idéntica en cualquier sistema.

    En este tema aprenderemos a preparar un equipo Windows para trabajar con Docker Desktop y a instalar Portainer, una herramienta gráfica que facilita la gestión de contenedores.

    Esta instalación será la base de todos los proyectos que realizaremos posteriormente.


    1. ¿Por qué Docker necesita Linux en Windows?

    Docker utiliza tecnologías propias del kernel de Linux como:

    • namespaces → aislamiento de procesos
    • cgroups → control de recursos
    • union filesystems → capas de almacenamiento

    Windows no dispone de estas tecnologías de forma nativa.

    La solución es WSL2.


    ¿Qué es WSL?

    WSL (Windows Subsystem for Linux) es una característica de Windows que permite ejecutar un kernel real de Linux dentro del sistema operativo sin necesidad de usar una máquina virtual tradicional.

    • No es un emulador.
    • No es una traducción de comandos.
    • Es Linux funcionando dentro de Windows.

    Ventajas de WSL2 frente a una VM clásica:

    • Arranque casi instantáneo
    • Menor consumo de memoria
    • Mejor rendimiento de disco
    • Integración directa con el sistema

    Docker Desktop utiliza WSL2 como motor de virtualización.

    👉 Sin WSL2, Docker simplemente no puede funcionar correctamente en Windows moderno.



    3. Activar la virtualización

    La virtualización debe estar habilitada en la BIOS/UEFI. Si has estado trabajando con maquinas virtuales con Virtual Box o VMWare seguro que ya lo tienes.

    Cómo comprobarlo
    1. Abrir el Administrador de tareas
    2. Ir a la pestaña Rendimiento → CPU

    Debe aparecer:

    Virtualización: Habilitada
    

    Si está deshabilitada:

    • Reiniciar el equipo
    • Entrar en BIOS/UEFI
    • Activar alguna de estas opciones:
    Intel VT-x
    Intel Virtualization Technology
    AMD-V
    SVM Mode
    

    Guardar cambios y reiniciar.


    4. Instalación de WSL2

    Abrir PowerShell como administrador.

    Ejecutar:

    wsl --install
    

    Este comando realiza automáticamente:

    • Instalación del kernel Linux
    • Activación de componentes necesarios
    • Instalación de Ubuntu
    • Configuración de WSL2 como versión por defecto

    Reiniciar el equipo cuando lo solicite.


    Comprobar que WSL2 está funcionando

    wsl -l -v
    

    Resultado esperado:

    NAME      STATE    VERSION
    Ubuntu    Running  2
    

    Si aparece versión 1:

    wsl --set-version Ubuntu 2
    

    5. Instalación de Docker Desktop

    Descargar desde la web oficial: https://www.docker.com/products/docker-desktop/

    Evitar instaladores de terceros.


    Instalación

    Ejecutar el instalador.

    Durante el proceso es MUY importante verificar que esté marcada la opción:

    Use WSL 2 instead of Hyper-V

    Esto permitirá que Docker funcione con el backend moderno.

    Finalizar la instalación y reiniciar si es necesario.


    6. Primer arranque de Docker

    Abrir Docker Desktop desde el menú inicio.

    El primer arranque puede tardar unos minutos.

    Cuando Docker esté listo aparecerá el mensaje:

    Docker is running
    

    Verificación desde terminal

    Abrir PowerShell o CMD:

    docker version
    

    Si todo está correcto, se mostrará información del cliente y del servidor Docker.

    Probar el primer contenedor:

    docker run hello-world
    

    Si aparece un mensaje de bienvenida, la instalación es correcta.

    Este pequeño contenedor confirma que:

    • Docker descarga imágenes
    • Puede crear contenedores
    • El motor funciona

    7. Configuración recomendada de Docker Desktop

    Ir a:

    Settings → Resources
    

    Asignación recomendada:

    • RAM: 4–6 GB
    • CPU: 2 o más
    • Swap: 1–2 GB

    Si los equipos son potentes, aumentar estos valores mejora la experiencia.


    8. ¿Qué es Portainer?

    Portainer es una interfaz web que permite administrar Docker sin depender únicamente de la terminal.

    Con Portainer es posible:

    • Crear contenedores
    • Gestionar imágenes
    • Administrar volúmenes
    • Supervisar recursos
    • Eliminar servicios

    Es una herramienta muy utilizada en entornos profesionales y facilita enormemente el aprendizaje inicial.


    9. Instalación de Portainer

    Docker desktop permite instalar Portainter como un plugin mas.

    Si deseas hacerlo desde terminal tambien puedes:

    Crear un volumen para almacenar los datos de Portainer.

    docker volume create portainer_data
    

    Ahora ejecutamos el contenedor:

    docker run -d -p 9443:9443 \
    --name portainer \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v portainer_data:/data \
    portainer/portainer-ce
    

    ¿Qué estamos haciendo?

    • -d → ejecuta el contenedor en segundo plano
    • -p 9443:9443 → expone la interfaz web
    • docker.sock → permite a Portainer comunicarse con Docker
    • volumen /data → guarda la configuración

    10. Primer acceso a Portainer

    Abrir el navegador:

    https://localhost:9443
    

    Es normal que el navegador advierta sobre el certificado.

    Continuar igualmente.




    Problemas habituales

    Docker no arranca

    Generalmente ocurre porque:

    • WSL no está activo
    • Virtualización deshabilitada
    • Conflictos con Hyper-V

    Solución típica:

    wsl --update
    wsl --shutdown
    

    Reiniciar Docker.


    Error de memoria

    Asignar más RAM desde:

    Settings → Resources
    

    WSL extremadamente lento

    Ejecutar:

    wsl --shutdown
    

    Y reiniciar Docker.


    A partir de aquí comenzaremos a trabajar con:

    • imágenes
    • contenedores
    • redes
    • volúmenes
    • orquestación

  • Docker desde Terminal

    Docker desde Terminal

    Antes de comenzar la misión, tu equipo debe estar preparado.

    Docker será el motor que dará vida a toda la infraestructura.

    Instalar Docker correctamente desde la terminal en Ubuntu utilizando el repositorio oficial.

    Evita instalar versiones antiguas desde repositorios genéricos.

    Queremos herramientas profesionales.


    Actualizar el sistema

    sudo apt update
    sudo apt upgrade -y
    

    Esto reduce la probabilidad de conflictos de dependencias.

    Los ingenieros prudentes actualizan primero.


    Instalar paquetes necesarios

    sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
    

    Estos paquetes permiten a Ubuntu comunicarse de forma segura con repositorios externos.


    Añadir la clave oficial de Docker

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
    

    Una clave GPG verifica que el software proviene de la fuente legítima.

    Sin esto, cualquiera podría hacerse pasar por Docker.

    Y eso sería… una idea terrible.


    Añadir el repositorio oficial

    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    

    Ahora Ubuntu sabrá dónde buscar Docker.


    Instalar Docker Engine

    sudo apt update
    sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
    

    Aquí ocurre la magia.


    Verificar la instalación

    sudo systemctl status docker
    

    Debe aparecer como:

    👉 active (running)

    Ahora prueba:

    sudo docker run hello-world
    

    Si ves el mensaje de bienvenida…

    Docker está vivo.


    MUY recomendado — Usar Docker sin sudo

    Trabajar con sudo constantemente es incómodo.

    Haz esto:

    sudo usermod -aG docker $USER
    

    Después CIERRA SESIÓN o reinicia.

    No es opcional — el cambio de grupo necesita recargar permisos.

    Comprueba:

    docker run hello-world
    

    Video de la lección

    Crear y ejecutar contenedores

    Contenedor interactivo básico

    docker run -it ubuntu
    

    Qué ocurre aquí:

    • run → crea el contenedor si no existe
    • -i → mantiene STDIN abierto
    • -t → asigna terminal
    • ubuntu → imagen base

    Si no está descargada, Docker la bajará automáticamente.

    Para salir sin detener el contenedor:

    Ctrl + P + Q
    

    Para salir deteniéndolo:

    exit
    

    Nombrar un contenedor

    docker run -it --name mi-ubuntu ubuntu
    

    Nombrar contenedores evita trabajar con IDs largos e ilegibles.

    Tu yo del futuro te lo agradecerá.


    Persistencia usando carpeta del host

    docker run --name mi-ubuntu -it -v /datos-persistentes:/datos ubuntu
    

    Qué significa esto:

    HOST → CONTENEDOR
    /datos-persistentes → /datos
    

    Todo lo que guardes en /datos sobrevivirá aunque borres el contenedor.

    Si la carpeta no existe, Docker la crea.


    Persistencia usando volumen Docker (RECOMENDADO)

    Primero crea el volumen:

    docker volume create mi-volumen
    

    Ahora úsalo:

    docker run --name mi-ubuntu -it -v mi-volumen:/datos ubuntu
    

    👉 Docker gestionará la ubicación real del almacenamiento.

    Ventajas:

    • Más seguro
    • Mejor rendimiento
    • Independiente del sistema de carpetas

    ⚠️ Nota para Windows

    docker run -it -v C:\ruta\local:/ruta/en/contenedor ubuntu
    

    En Ubuntu Desktop NO se usa esta sintaxis.

    La equivalente sería:

    docker run -it -v /home/usuario/datos:/datos ubuntu
    

    Consultar información del sistema Docker

    Ver contenedores en ejecución

    docker ps
    

    Ver TODOS los contenedores

    docker ps -a
    

    Aquí aparecerán también los detenidos.

    Muy útil para debugging.


    Ver imágenes descargadas

    docker images
    

    O su versión moderna:

    docker image ls
    

    Crear imágenes personalizadas

    Imagina que has instalado paquetes dentro del contenedor y no quieres repetir el proceso.

    Puedes congelar ese estado.

    docker commit mi-ubuntu mi-imagen-personalizada
    

    Ahora tienes una nueva imagen lista para usar:

    docker run -it mi-imagen-personalizada
    

    📌 Importante para mentalidad profesional:

    docker commit es útil para aprender…

    Pero en entornos reales se prefiere usar Dockerfile porque permite reproducibilidad.


    Operaciones con contenedores

    Arrancar un contenedor detenido

    docker start mi-ubuntu
    

    Arrancar y conectarte directamente

    docker start -ai mi-ubuntu
    

    Parámetros:

    • -a → attach (conectar terminal)
    • -i → modo interactivo

    Ejecutar comandos dentro de un contenedor activo

    docker exec -it mi-ubuntu bash
    

    Esto abre una nueva shell.

    Extremadamente usado por administradores.


    Eliminar un contenedor

    ⚠️ Debe estar detenido.

    docker rm mi-ubuntu
    

    Para forzar:

    docker rm -f mi-ubuntu
    

    Limpiar contenedores detenidos automáticamente

    docker container prune
    

    Docker pedirá confirmación.

    Este comando es famoso por liberar gigas de disco en laboratorios.

  • Del Contenedor a la Base de Datos: MySQL Docker + Workbench

    Del Contenedor a la Base de Datos: MySQL Docker + Workbench

    Vamos a creae una base de datos naciendo en un contenedor, y desde fuera un cliente elegante (Workbench) hablando con ella a través del vacío digital. Eso es red, puertos y aislamiento en acción.

    1. Crear contenedor MySQL.
    2. Publicar puerto al host.
    3. Conectarse desde MySQL Workbench.
    4. Ver que el contenedor es “otro sistema”, pero accesible.

    Arquitectura:

    Workbench (Host)  →  localhost:3306  →  Contenedor MySQL

    Paso 1 — Crear contenedor MySQL

    En terminal:

    docker run -d \
      --name mysql-demo \
      -e MYSQL_ROOT_PASSWORD=1234 \
      -e MYSQL_DATABASE=demo \
      -p 3306:3306 \
      mysql:8

    Qué significa cada parte (esto es lo que debes explicar)

    • -d → modo daemon (segundo plano)
    • --name mysql-demo → nombre del contenedor
    • MYSQL_ROOT_PASSWORD → password del root (obligatorio)
    • MYSQL_DATABASE → crea BD inicial
    • -p 3306:3306 → publica puerto MySQL al host
    • mysql:8 → imagen oficial

    Paso 2 — Verificar que el contenedor está vivo

    docker ps

    Debe aparecer algo como:

    mysql-demo   mysql:8   Up ...   0.0.0.0:3306->3306/tcp

    Si no arranca:

    docker logs mysql-demo

    MySQL tarda unos segundos en inicializar. Paciencia científica.


    Paso 3 — Conectar desde MySQL Workbench

    En Workbench → New Connection

    Parámetros:

    • Host: 127.0.0.1
    • Port: 3306
    • User: root
    • Password: 1234

    Test Connection → Connect.

    Si todo va bien, verás la BD demo.


    Paso 4 — Prueba real

    En Workbench ejecuta:

    CREATE TABLE alumnos (
      id INT AUTO_INCREMENT PRIMARY KEY,
      nombre VARCHAR(50)
    );
    
    INSERT INTO alumnos (nombre) VALUES ('Neo'), ('Trinity');
    
    SELECT * FROM alumnos;

    Luego demuestra algo mágico:

    Entra al contenedor

    docker exec -it mysql-demo mysql -uroot-p1234

    Dentro:

    USE demo;
    SELECT * FROM alumnos;

    Los datos están ahí → Workbench y contenedor hablan con la misma base.

    Eso hace que los alumnos comprendan el concepto de servicio expuesto por red.

    Problemas típicos (para que no te sabotee el universo)

    Puerto ocupado

    Si tienes MySQL local:

    lsof -i :3306

    Cambia puerto:

    -p3307:3306

    Y en Workbench → puerto 3307.


    No conecta

    Comprobar:

    docker ps
    docker logs mysql-demo

    Esperar inicialización (MySQL tarda).


    Workbench no conecta pero CLI sí

    A veces el plugin de auth:

    docker exec -it mysql-demo mysql -uroot-p1234

    En SQL

    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '1234';
    FLUSH PRIVILEGES;
  • Del Código al Contenedor: Dominando Dockerfile Paso a Paso

    Del Código al Contenedor: Dominando Dockerfile Paso a Paso

    Un Dockerfile es una receta: describes pasos para construir una imagen.
    Luego ejecutas esa imagen y eso crea un contenedor.

    • Dockerfile: receta
    • Imagen: “plato ya cocinado” (plantilla)
    • Contenedor: “plato servido” (instancia en ejecución)

    Primer Dockerfile “Hola Mundo” (Python)

    Estructura de proyecto:

    mkdir dockerfile-101 && cd dockerfile-101
    mkdir app

    Crea app/app.py:

    cat > app/app.py << 'EOF'
    print("Hola desde un contenedor 😼")
    EOF

    Crea Dockerfile:

    FROM python:3.12-slim
    
    WORKDIR /app
    COPY app/ /app/
    
    CMD ["python", "app.py"]
    EOF

    Construir la imagen:

    docker build -t hola-dockerfile:1.0 .

    Ejecutar:

    docker run --rm hola-dockerfile:1.0

    Puntos clave :

    • Qué hace FROM, WORKDIR, COPY, CMD.
    • Por qué CMD va en formato lista (["..."]) y no como string.

    FROM

    Define la imagen base sobre la que se construirá la nueva imagen.

    Ejemplo:

    FROM python:3.12-slim

    Qué ocurre:

    • Docker descarga la imagen si no existe localmente.
    • Marca el punto de partida del sistema de archivos del contenedor.
    • Solo puede existir una FROM por etapa (en multi-stage puede haber varias).

    Buenas prácticas:

    • Usar imágenes ligeras (alpine, slim).
    • Evitar latest en producción (usar versiones concretas).

    WORKDIR

    Establece el directorio de trabajo dentro del contenedor.
    Equivale a ejecutar cd permanentemente para las siguientes instrucciones.

    WORKDIR /app

    Qué ocurre:

    • Si el directorio no existe, Docker lo crea automáticamente.
    • Todas las instrucciones posteriores (COPY, RUN, CMD) se ejecutan desde esa ruta.

    Ventaja:
    Evita rutas largas y mejora la legibilidad.


    COPY

    Copia archivos desde el sistema host (tu máquina) al contenedor.

    COPY app/ /app/

    Qué ocurre:

    • Se copian los archivos del contexto de build (directorio actual).
    • Se crea una nueva capa en la imagen.
    • Si cambia cualquier archivo copiado, Docker invalida la caché desde ese punto.

    Diferencia con ADD:

    • COPY solo copia archivos.
    • ADD puede descomprimir tar y descargar URLs (menos predecible, se recomienda COPY).

    Buenas prácticas:
    Copiar primero dependencias y luego código para aprovechar la caché:

    COPY requirements.txt .RUN pip install -r requirements.txtCOPY . .

    CMD

    Define el comando por defecto que ejecutará el contenedor al iniciarse.

    CMD ["python", "app.py"]

    Si el usuario pasa otro comando en docker run, este sobrescribe CMD.

    Ejemplo:

    docker run mi-imagen python otro.py

    ¿Por qué CMD debe ir en formato lista?

    Existen dos formas:

    Forma shell (string)

    CMD python app.py

    Docker lo ejecuta así:

    /bin/sh -c "python app.py"

    Problemas:

    • Se crea un proceso intermedio (sh).
    • Señales Unix (SIGTERM, SIGINT) no llegan correctamente al proceso principal.
    • Problemas con contenedores que deben parar limpiamente (servidores, apps, etc.).

    Forma exec (lista) — RECOMENDADA

    CMD ["python", "app.py"]

    Ventajas:

    • No usa shell intermedia.
    • El proceso es PID 1 dentro del contenedor.
    • Recibe correctamente señales del sistema.
    • Comportamiento más predecible.
    • Es el estándar en producción.

    Regla mental:
    Si el comando no necesita shell (|, &&, variables, etc.) → usar formato lista.

    EXPOSE

    Documenta qué puerto usa la aplicación dentro del contenedor.

    EXPOSE80

    Importante:

    • No abre puertos.
    • Solo sirve como metadato informativo.
    • Para publicar puerto se usa -p en docker run.

    Ejemplo:

    docker run -p8080:80 mi-imagen

    ENV

    Define variables de entorno dentro del contenedor.

    ENV APP_ENV=production

    Uso típico:

    • Configuración de aplicaciones
    • Rutas
    • Flags de ejecución

    Acceso en Python:

    importosprint(os.getenv("APP_ENV"))

    RUN

    Ejecuta comandos durante la construcción de la imagen.

    RUN apt update && apt install -y curl

    Diferencia con CMD:

    • RUN ocurre en build
    • CMD ocurre en runtime

    Cada RUN crea una capa nueva → conviene agrupar comandos.


    Dockerfile con dependencias (requests) + capas

    Cambia app/app.py:

    
    
    
    
    
    import requests
    print("IP pública (si hay salida a Internet):", requests.get("https://api.ipify.org").text)
    

    Crea app/requirements.txt:

    cat > app/requirements.txt << 'EOF'
    requests==2.32.3
    EOF

    Actualiza Dockerfile (truco de cache y capas):

    FROM python:3.12-slim
    
    WORKDIR /app
    
    # 1) Copiamos requirements primero (mejor cache)
    COPY app/requirements.txt /app/requirements.txt
    RUN pip install --no-cache-dir -r requirements.txt
    
    # 2) Copiamos el código después
    COPY app/ /app/
    
    CMD ["python", "app.py"]
    

    Rebuild y run:

    docker build -t ip-check:1.0 .
    docker run --rm ip-check:1.0

    Lección nerd útil: si solo cambia el código, Docker reutiliza la capa de pip install y construye más rápido.


    .dockerignore (para no meter “basura” en la imagen)

    Crea .dockerignore:

    .git
    __pycache__/
    *.pyc
    *.log
    .DS_Store
    

    Crear un archivo “gordo” y comprobar que no entra:

    dd if=/dev/zero of=archivo_gordo.bin bs=1M count=50
    docker build -t ignore-test:1.0 .


    Dockerfile para una web (Nginx estático) en 30 segundos

    Estructura:

    mkdir -p web
    cat > web/index.html << 'EOF'
    <h1>Hola desde Nginx en Docker</h1>
    <p>Si ves esto, EXPOSE era postureo, pero ayuda a documentar 😄</p>
    EOF

    Dockerfile:

    cat > Dockerfile << 'EOF'
    FROM nginx:alpine
    COPY web/ /usr/share/nginx/html/
    EXPOSE 80
    EOF

    Build + run:

    docker build -t web-nginx:1.0 .
    docker run --rm -p 8080:80 web-nginx:1.0

    Abrir: http://localhost:8080


    Ejemplos

    Ejemplo: Dockerfile para una app en Python

    FROM python:3.11-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    EXPOSE 5000
    
    CMD ["python", "app.py"]

    Este caso muestra cómo:

    • Se usa una imagen base de Python.
    • Se instala lo necesario con pip.
    • Se copia el código de la aplicación.
    • Se expone el puerto del servicio (por ejemplo, Flask).
    • Se ejecuta la app con CMD.

    Ejemplo: Dockerfile para PHP + Apache

    FROM php:8.2-apache
    COPY ./htdocs /var/www/html/
    EXPOSE 80

    Así pueden tener un servidor web con PHP.
    Luego ejecutan:

    docker build -t miwebphp . docker run -d -p 8080:80 miwebphp

    Buenas prácticas

    • Siempre usa imágenes base oficiales.
    • Agrupa las instalaciones en una sola instrucción RUN para reducir el tamaño de la imagen.
    • Usa .dockerignore para no copiar archivos innecesarios.
    • Define variables con ENV si hay configuraciones reutilizables.
    • Usa ENTRYPOINT cuando quieras ejecutar siempre el mismo comando, incluso si el usuario añade argumentos extra.

    Instrucción WORKDIR

    WORKDIR establece el directorio de trabajo dentro del contenedor.
    Equivale a hacer un cd /app dentro del entorno del contenedor antes de ejecutar los siguientes comandos.

    Por ejemplo:

    FROM python:3.11-slim
    WORKDIR /app
    COPY . .
    RUN pip install -r requirements.txt
    
    CMD ["python", "app.py"]

    Qué hace realmente:

    1. Crea el directorio si no existe (/app en este caso).
    2. Cambia el contexto: a partir de esa línea, todos los comandos (COPYRUNCMD, etc.) se ejecutan dentro de /app.

    Así, COPY . . copia el contenido del proyecto local dentro del contenedor en /app, y python app.py se ejecutará desde ahí.


    Sin WORKDIR

    Si no la usas, Docker ejecuta todo desde / (la raíz del contenedor).
    Ejemplo:

    FROM python:3.11-slim
    
    COPY . .
    
    CMD ["python", "app.py"]

    Esto también funcionará, pero el código quedará desperdigado en / — algo poco limpio y poco profesional.


    ¿Qué son las variables de entorno en Docker?

    Las variables de entorno (ENV) son valores que se inyectan en el entorno del contenedor y que las aplicaciones pueden usar para configurarse.

    Por ejemplo:

    • Contraseña del root
    • Nombre de la base de datos
    • Usuario y contraseña de aplicación

    Docker las pasa al contenedor con la instrucción ENV en el Dockerfile o con la opción -e en el docker run.


    Ejemplo básico de Dockerfile con MySQL

    # Imagen base oficial de MySQL
    
    FROM mysql:8.0
    
    # Variables de entorno
    
    ENV MYSQL_ROOT_PASSWORD=supersegura
    
    ENV MYSQL_DATABASE=tienda
    
    ENV MYSQL_USER=usuario
    
    ENV MYSQL_PASSWORD=1234
    
    # Exponer el puerto de MySQL
    
    EXPOSE 3306

    Explicación:

    • MYSQL_ROOT_PASSWORD: establece la contraseña del usuario root.
    • MYSQL_DATABASE: crea automáticamente una base de datos llamada tienda.
    • MYSQL_USER y MYSQL_PASSWORD: crean un usuario adicional con permisos sobre esa base.
    • EXPOSE 3306: indica el puerto por defecto del servicio.

    Construcción y ejecución

    Construir la imagen:

    docker build -t mysql-demo .

    Ejecutar el contenedor:

    docker run -d -p 3306:3306 --name contmysql mysql-demo

    Con eso, MySQL arrancará con la configuración establecida en las variables del Dockerfile.


    Alternativa más flexible (sin tocar el Dockerfile)

    También se pueden pasar las variables en tiempo de ejecución, lo que se recomienda para producción (para no dejar contraseñas dentro del Dockerfile):

    docker run -d -p 3306:3306 \
    
    --name mysql-demo \
    
    -e MYSQL_ROOT_PASSWORD=supersegura \
    
    -e MYSQL_DATABASE=tienda \
    
    -e MYSQL_USER=usuario \
    
    -e MYSQL_PASSWORD=1234 \
    
    mysql:8.0

    Así puedes usar directamente la imagen oficial de MySQL sin construir una nueva.


    Comprobación dentro del contenedor

    Para entrar al contenedor y verificar:

    docker exec -it mysql-demo mysql -u root -p

    Introduce la contraseña (supersegura) y luego:

    SHOW DATABASES;

    Verás que existe la base tienda.


    Usando un .env externo

    Otra práctica útil es usar un archivo .env:

    Archivo .env

    MYSQL_ROOT_PASSWORD=supersegura
    
    MYSQL_DATABASE=tienda
    
    MYSQL_USER=usuario
    
    MYSQL_PASSWORD=1234

    Y luego ejecutarlo con:

    docker run -d --env-file .env -p 3306:3306 --name mysql-demo mysql:8.0

    LABORATORIO – TAREA

    Montar una infraestructura de laboratorio Dockerizada donde cada contenedor representa una parte de una red vulnerable, simulando un pequeño entorno que deben administrar, securizar o incluso “atacar” de forma controlada.


    Cada alumno desplegará una red interna en su máquina virtual Ubuntu Server, con varios contenedores Docker que simulen los componentes de una empresa ficticia hackeable llamada:

    «CyberCorp Ltd.»

    El propósito es:

    • Divertirse con un entorno “ethical hacking friendly”.
    • Aprender a crear y gestionar contenedores.
    • Comprender la comunicación entre ellos
    • Aplicar conceptos de seguridad: contraseñas, puertos, logs, aislamiento, backups.

    Infraestructura propuesta

    ServicioImagen baseRol / DescripciónPuertos
    nginx-webnginx:latestPágina corporativa vulnerable (HTML + PHP)8080
    db-servermysql:8.0Base de datos de empleados con credenciales débiles3306
    ftp-serverdelfer/alpine-ftp-serverServidor FTP para intercambio de archivos21
    mail-servermaildev/maildevServidor SMTP simulado (visualización de correos en web)1080
    monitorgrafana/grafanaPanel de monitorización interno3000
    attackerkalilinux/kali-rollingContenedor con herramientas ofensivasshell interactiva
    loggerfluentdCentralización de l

    1) Preparación en la VM (comandos iniciales)

    # Actualizar y asegurarnos de tener Docker
    sudo apt update && sudo apt install -y docker.io
    # Iniciar y activar Docker
    sudo systemctl enable --now docker
    # Añadir tu usuario al grupo docker (opcional, cerrar sesión/reiniciar)
    sudo usermod -aG docker $USER
    # Crear red y volumenes
    docker network create cybernet
    docker volume create mysql_data
    docker volume create web_html
    

    2) Estructura de carpetas (ejemplo) /home/usuario/hack-containers/

    ├─ web/
    │  ├─ Dockerfile
    │  └─ html/
    │     ├─ index.php
    │     └─ secret/flag.txt
    ├─ mysql/
    │  ├─ Dockerfile
    │  └─ init-db/
    │     └─ init.sql
    ├─ ftp/
    │  └─ Dockerfile
    ├─ mail/
    │  └─ Dockerfile
    ├─ attacker/
    │  └─ Dockerfile
    └─ logger/
       └─ Dockerfile

    3) Dockerfile + archivos — ejemplos

    A) MySQL (mysql/Dockerfile)

    Usamos la imagen oficial de MySQL como base, y añadimos un init SQL.

    FROM mysql:8.0
    
    # Copiamos scripts de inicialización (se ejecutan al primer arranque)
    
    COPY init-db/ /docker-entrypoint-initdb.d/ VOLUME ["/var/lib/mysql"]
    
    EXPOSE 3306

    mysql/init-db/init.sql (ejemplo con credenciales débiles y tabla)

    CREATE DATABASE empleados;
    
    USE empleados;
    
    CREATE TABLE usuarios ( id INT AUTO_INCREMENT PRIMARY KEY, usuario VARCHAR(50), password VARCHAR(50) );
    
    INSERT INTO usuarios (usuario, password) VALUES ('admin','admin123');

    Construir y ejecutar:

    cd mysql
    
    docker build -t ctf-mysql:1.0 . docker run -d --name mysql --network cybernet \
    
    -e MYSQL_ROOT_PASSWORD=rootroot \
    
    -v mysql_data:/var/lib/mysql \
    
    ctf-mysql:1.0

    B) Web vulnerable (PHP + Apache) (web/Dockerfile)

    FROM php:8.2-apache
    
    # Copiamos el código vulnerable
    
    COPY html/ /var/www/html/
    
    # Habilitamos mod_rewrite por si hace falta
    
    RUN a2enmod rewrite
    
    EXPOSE 80

    web/html/index.php (vulnerable ejemplo: login sin sanitizar — para SQLi)

    <?php
    $conn = new mysqli('mysql','root','rootroot','empleados');
    if(isset($_GET['user'])){
        $user = $_GET['user'];
        $res = $conn->query("SELECT * FROM usuarios WHERE usuario = '$user'");
        if($res && $res->num_rows){
            echo "Usuario encontrado<br>";
        } else {
            echo "No encontrado";
        }
    } else {
        echo '<a href="?user=admin">Comprobar usuario admin</a>';
    }
    ?>

    web/html/secret/flag.txt

    FLAG{has_encontrado_la_bandera_web}

    Construir y ejecutar:

    cd web
    docker build -t ctf-web:1.0 .
    docker run -d --name web --network cybernet \
      -p 8080:80 \
      -v web_html:/var/www/html \
      ctf-web:1.0
    # Copiar el html local al volumen (una sola vez si quieres)
    docker cp html/. web:/var/www/html/

    Nota: en index.php se conecta a host mysql (nombre del contenedor) — así los containers se resuelven por nombre dentro de la red cybernet.


    C) FTP (ftp/Dockerfile) — ejemplo simple con vsftpd

    FROM alpine:3.18
    RUN apk add --no-cache vsftpd openrc
    COPY ftp-config/vsftpd.conf /etc/vsftpd/vsftpd.conf
    # Creamos usuario demo
    RUN adduser -D -h /home/usuario ftpuser && \
        echo "ftpuser:ftp123" | chpasswd && \
        mkdir -p /home/usuario/ftp_upload && chown ftpuser:ftpuser /home/usuario/ftp_upload
    EXPOSE 21 20
    CMD ["sh", "-c", "vsftpd /etc/vsftpd/vsftpd.conf"]

    ftp-config/vsftpd.conf puede ser muy simple para prácticas. (Puedes proveerlo a los alumnos o generar uno básico.)

    Construir y ejecutar:

    cd ftp
    
    docker build -t ctf-ftp:1.0 .
    
    docker run -d --name ftp --network cybernet -p 2121:21 ctf-ftp:1.0

    (Nota: FTP activo/pasivo considera puertos extra; para la práctica usarlo localmente y documentar.)


    D) Maildev (mail server de pruebas) — Dockerfile mínimo

    FROM maildev/maildev:latest 
    EXPOSE 1080 25

    Construir y ejecutar:

    cd mail
    
    docker build -t ctf-mail:1.0 .
    
    docker run -d --name mail --network cybernet -p 1080:1080 ctf-mail:1.0

    Maildev ofrece UI web en :1080 para ver emails enviados por la aplicación vulnerable.


    E) Logger / ELK ligero (logger/Dockerfile) — ejemplo usando busybox+fluentd sería largo.

    Puedes usar Fluentd o simplemente montar un contenedor que recoja docker logs desde fuera. Para simplicidad, propondré un contenedor fluentd base:

    FROM fluent/fluentd:v1.14-1
    
    EXPOSE 24224

    Construir y ejecutar:

    cd logger
    
    docker build -t ctf-logger:1.0 .
    
    docker run -d --name logger --network cybernet -p 24224:24224 ctf-logger:1.0

    F) Contenedor atacante (Kali) (attacker/Dockerfile)

    Instalamos unas herramientas útiles (nmap, nikto, sqlmap, hydra).

    FROM kalilinux/kali-rolling
    RUN apt update && apt install -y nmap nikto sqlmap hydra netcat-openbsd curl && apt clean
    WORKDIR /root
    CMD ["/bin/bash"]

    Construir y ejecutar (modo interactivo):

    cd attacker
    
    docker build -t ctf-kali:1.0 .
    
    docker run -it --name kali --network cybernet ctf-kali:1.0

    Dentro del contenedor atacas la red cybernet (ej. nmap -sV -p- web).


    4) Notas sobre volúmenes y persistencia

    Para copiar archivos iniciales al volumen, puedes docker cp como mostré.

    Mysql usa -v mysql_data:/var/lib/mysql para persistencia.

    Web usamos -v web_html:/var/www/html para poder editar fuera y reflejar cambios.

    RECUERDA

    # Ver containers
    docker ps -a

    # Logs de un contenedor
    docker logs web

    # Entrar a un contenedor
    docker exec -it mysql bash
    docker exec -it kali bash

    # Consultar red
    docker network inspect cybernet

    # Inspeccionar variables de entorno de un contenedor
    docker inspect -f ‘{{range .Config.Env}}{{println .}}{{end}}’ mysql

    Retos

    1. Recon: desde kali hacer nmap -sV -p- --open 172.18.0.0/16 y documentar servicios.
    2. FTP-cred: conectarse a FTP (ftp user:ftpuser/ftp123) y buscar creds.txt.
    3. DB login: usar credenciales encontradas para entrar en MySQL (mysql -u admin -p admin123).
    4. SQLi: Explorar index.php y realizar un SQL injection básico para sacar datos o la flag.txt.
      • Ejemplo payload: '?user=admin' vs '?user=admin' OR '1'='1'
    5. Mail: desde web, forzar envío de correo a Maildev y ver en la UI :1080.
    6. Detección: activar logs/monitor y buscar patrones sospechosos (pings, intentos SQL).
    7. Hardening: cambiar la configuración, cerrar puertos, poner contraseñas robustas y documentar.