Aprender Linux es una de las habilidades más valiosas en la industria de la tecnología. Te ayuda a realizar las tareas más rápidamente y de manera más eficiente. Muchos de los servidores poderosos y supercomputadoras del mundo ejecutan Linux.

Mientras que te fortalece en tu rol actual, aprender Linux también te puede ayudar en transicionar a otras carreras tech como DevOps, Ciberseguridad, y Computación en la Nube.

En este manual, aprenderás las bases de la línea de comandos de Linux, y luego transitaremos a temas más avanzados como programación de scripts y administración de sistema. Sea que eres nuevo en Linux o que ya has estado usándolo por años, este libro tiene algo para ti.

Nota Importante: Todos los ejemplos en este libro son mostrados en Ubuntu 22.04.2 LTS (Jammy Jellyfish). La mayoría de las herramientas de línea de comandos son más o menos los mismos en otras distribuciones. Sin embargo, algunas aplicaciones de escritorio (GUI) y comandos podrían diferir si estás trabajando en otra distribución de Linux.

Tabla de Contenidos

Parte 1: Introducción a Linux

Parte 2: Introducción al Shell de Bash y los Comandos de Sistema

Parte 3: Entendiendo tu Sistema de Linux

Parte 4: Manejando Archivos desde la Línea de Comando

Parte 5: Lo Esencial sobre Edición de Texto en Linux

Parte 6: La Programación en Bash

Parte 7: Manejando Paquetes de Software en Linux

Parte 8: Temas de Linux Avanazados

Conclusión

Parte 1: Introducción a Linux

1.1. Comenzando con Linux

¿Qué es Linux?

Linux es un Sistema Operativo de código abierto que está basado en el Sistema Operativo Unix. Fue creado por Linus Torvalds in 1991.

El Código Abierto significa que el código fuente del Sistema Operativo está disponible al público. Este le permite a cualquiera modificar el código origina, personalizarlo, y distribuir el Sistema Operativo a usuarios potenciales.

¿Por qué deberías aprender sobre Linux?

En el escenario de los centros de datos de hoy, Linux y Microsoft Windows se destacan como los contendientes, con Linux teniendo la mayor parte.

Aquí hay varias razones convincentes para aprender Linux:

  • Dada la prevalencia del alojamiento de Linux, hay una alta chance que tu aplicación será alojado en Linux. Así que aprender Linux como un desarrollador se convierte cada vez más valorado.
  • Con la computación en la nube se convierte en la norma, las chances son altas que tus instancias de la nube se basará en Linux.
  • Los servidores de Linux como la fundación para muchos Sistemas Operativos para el Internet de las Cosas (IoT) y aplicaciones móviles.
  • En IT, hay muchas oportunidades para aquellos hábiles en Linux.

¿Qué significa que Linux es un Sistema Operativo de código abierto?

Primero, ¿qué es código abierto? Software de código abierto cuyo código fuente es accesible gratuitamente, permitiendo a cualquier utilizar, modificar y distribuirlo.

Cuando sea que el código fuente fuese creado, se considera automáticamente protegido por derechos de autor, y su distribución se rige por el titular de los derechos de autor a través de licencias de software.

En contraste al código abierto, el software propietario o de código cerrado restringe el acceso a su código fuente. Solamente los creadores pueden verlos, modificarlos o distribuirlos.

Linux es ante todo de código abierto, lo que significa que su código fuente está disponible de forma gratuita. Cualquiera puede verlo, modificarlo, y distribuirlo. Los Desarrolladores desde cualquier lugar en el mundo pueden contribuir a sus mejoras. Esto sienta la fundación de la colaboración lo cual es un aspecto importante del software de código abierto.

Esto enfoque colaborativo ha llevado a la amplia adopción de Linux entre los servidores, computadoras de escritorio, sistemas embebidos, y dispositivos móviles.

El aspecto más interesante de Linux siendo de código abierto es que cualquier puede adaptar el sistema operativo a sus necesidades específicas sin ser restringido por las limitaciones de propiedad.

El SO (Sistema Operativo) Chrome utilizado por los Chromebooks está basado en Linux. Android, que impulsa a muchos teléfonos inteligentes, también está basado en Linux.

¿Qué es un Kernel de Linux?

El kernel es el componente central de un Sistema Operativo que gestiona la computadora y sus operaciones hardware. Maneja operaciones de memoria y el tiempo de CPU.

El kernel actúa como un puente entre aplicaciones y el proceso de datos a nivel de hardware usando la comunicación entre procesos y llamadas de sistema.

El kernel se carga en memoria primero cuando un Sistema Operativo comienza y permanece allí hasta que el sistema se apaga. Es responsable de tareas como la gestión de disco, gestión de tareas, y gestión de memoria.

Linux Kernel Layout showing interaction of kernal with applications and OS

Si estás interesado en saber cómo se ve el kernel de Linux, aquí está el enlace de Github.

¿Que es una distribución de Linux?

A este punto, sabes que puedes re-usar el código kernel de Linux, modificarlo, y crear un nuevo kernel. Puedes aún combinar diferentes utilidades y software para crear un Sistema Operativo completamente nuevo.

Una distribución de Linux o distro es una versión del Sistema Operativo Linux que incluye el kernel de Linux, utilidades de sistema, y otros software. Siendo de código abierto, una distribución de Linux es un esfuerzo colaborativo que involucra múltiples comunidades de desarrollo de código abierto independientes.¿Qué significa que una distribución sea derivado? Cuando dices que una distribución es "derivado" de otro, el nuevo distro está construido sobre la base o fundación del distro original. Esta derivación puede incluir el usar el sistema de gestión de paquetes (más sobre esto después), versión del kernel, y a veces las mismas herramientas de configuración.

Hoy, hay miles distribuciones de Linux para elegir, ofreciendo diferentes objetivos y criterios para seleccionar y soportar el software provisto por su distribución.

Las distribuciones varían uno del otro, pero generalmente tienen características en común.

  • Una distribución consiste de un kernel de Linux.
  • Soporta programas de espacio de usuario.
  • Una distribución podría ser pequeño y de un solo propósito o incluir miles de programas de código abierto.
  • Algunos medios para instalar y actualizar la distribución y sus componentes debería ser provistos.

Si ves la Línea de Tiempo de las Distribuciones de Linux, verás dos mayores distros: Slackware y Debian. Varias distribuciones son derivados de ellos. Por ejemplo, Ubuntu y Kali son derivados de Debian.

¿Cuáles son las ventajas de la derivación? Hay varias ventajas de la derivación. La Distribuciones derivadas pueden aprovechar la estabilidad, seguridad, y grandes repositorios de software de la distribución padre.

Cuando se construye sobre una fundación existente, los desarrolladores pueden conducir su enfoque y esfuerzo enteramente en las características especializadas de la nueva distribución. Los usuarios de distribuciones derivadas se pueden beneficiar de la documentación, el soporte de comunidad, y recursos ya disponibles para la distribución padre.

Algunas distribuciones de Linux populares son:

  1. Ubuntu: Uno de las distribuciones de Linux más usado y más popular. Es amigable y recomendado para los principiantes. Aprender más sobre Ubuntu aquí.
  2. Linux Mint: Basado en Ubuntu, Linux Mint provee una experiencia amigable con un enfoque en soporte de multimedia. Aprender más sobre Linux Mint aquí.
  3. Arch Linux: Popular entre usuarios experimentados, Arch es una distribución ligera y flexible dirigido a usuarios que prefieren un enfoque DIY. Aprender más sobre Arch Linux aquí.
  4. Manjaro: Basado en Arch Linux, Manjaro provee una experiencia amigable con software pre-instalado y herramientas sencillas de gestión del sistema. Aprender más sobre Manjaro aquí.
  5. Kali Linux: Kali Linux provee un conjunto comprensivo de herramientas de seguridad y está mayormente enfocado en ciberseguridad y hacking. Aprender más sobre Kali Linux aquí.

Cómo instalar y acceder a Linux

La mejor manera de aprender es aplicar los conceptos a medidas que avanzas. En esta sección, aprenderemos cómo instalar Linux en tu máquina así puedes seguirme. También aprenderás cómo acceder a Linux en una máquina con Windows.

Te recomiendo que sigas cualquiera de los métodos mencionados en esta sección para tener acceso a Linux así puedes seguirme.

Instalar Linux como el SO primario

Instalar Linux como el SO primario es la forma más eficiente de usar Linux, ya que puedes usar todo el poder de tu máquina.

En esta sección, aprenderás cómo instalar Ubuntu, el cual es uno de las distribuciones de Linux más popular. Dejé fuera de lista otras distribuciones por ahora, ya que quiero mantener las cosas sencillas. Siempre puedes explorar otras distribuciones una vez que te sientas cómodo con Ubuntu.

Paso 1 – Descargar el iso de Ubuntu: Ve al sitio web oficial y descarga el archivo iso. Asegúrate en seleccionar un lanzamiento estable que está caracterizado como "LTS". LTS significa "Soporte de Largo Término" (Long Term Support en inglés) lo que significa que puedes obtener seguridad gratuita y actualizaciones de mantenimiento por un tiempo prolongado (usualmente 5 años).

Paso 2 – Crea un pendrive bootable: Hay un número de softwares que puede crear un pendrive booteable. Recomiendo usar Rufus, ya que es bastante fácil de usar. Puedes descargarlo aquí.

Paso 3 – Iniciar desde el pendrive: Una vez que tu pendrive bootable está listo, insértalo y inicia desde el pendrive. El menú del boot depende de tu laptop. Puedes buscar en google el menú de boot para tu modelo de laptop.

Paso 4 – Sigue los pasos. Una vez, que el proceso de boot comience, selecciona try or install ubuntu.

Screen prompt to either try or install Ubuntu

El proceso tomará algo de tiempo. Una vez que el GUI aparece, puedes seleccionar el idioma, y el teclado, y continuar. Ingresa al inicio de sesión con tu nombre. Recuerda las credenciales ya que los necesitarás para inciar sesión en tu sistema y acceder a privilegios totales. Espera que la instalación se complete.

Paso 5 – Reinicia: Haz clic en reiniciar ahora y retira el pen drive.

Paso 6 – Inicia sesión: Inicia sesión con las credenciales que ingresaste anterioremente.

¡Y ahí está! Ahora puedes instalar aplicaciones y personalizar tu escritorio.

Ubuntu 22.04.4 LTS Desktop screen

Para una instalación avanzada, puedes explorar los siguientes temas:

  • Particionamiento de Disco.
  • Configurar la memoria de intercambio para permitir la hibernación.

Accediendo a la terminal

Una parte importante de este manual es aprender sobre la terminal donde ejecutarás todos los comandos y ver toda la magia. Puedes buscar en la terminal presionando la tecla "window" y escribiendo "terminal". Puedes fijar la Terminal en el dock donde otras aplicaciones están localizadas para un fácil acceso.

Search results for "terminal"
💡 The shortcut for opening the terminal is ctrl+alt+t

También puedes abrir la terminal desde una carpeta. Haz clic derecho donde estás y haz clic en "Abrir en Terminal". Esto abrirá la terminal en la misma ruta.

Opening the terminal with right click menu
Cómo usar Linux en una máquina Windows

A veces prodrías necesitar ejecutar tanto Linux como Windows lado a lado. Afortunadamente, hay varias maneras que puedes aprovechar de ambos mundos sin tener distintas computadoras para cada sistema operativo.

En esta sección, explorarás una pocas formas de usar Linux en una máquina de Linux. Algunos de ellos basados al navegador o basados en la nube y no necesita ninguna instalación de SO antes de usarlos.

Opción 1: "Dual-boot" Linux + Windows: Con dual boot, puedes instalar Linux juntamente con Windows en tu computadora, permitiéndote elegir qué Sistema Operativo usar al inicio.

Esto requierer particionar tu disco duro e instalar Linux en una partición separada. Con este enfoque, solamente puedes usar un sistema Operativo a la vez.

Opción 2: USar el Subsitema de Windows  para Linux  (WSL): El Subsistema para Linux provee una capa de comtabilidad que te permite ejecutar ejecutables binarios de Linux de forma nativa en WIndows.

Usando WSL tiene algunas ventajas. La configuración para WSL es sencilla y rápida. Es liviana comparado con los VMs donde tiene que aisgnar recursos desde la máquina anfitriona. No necesitas instalar ningún ISO o imagen de disco virtual para las máquinas Linux los cuales tienden a ser archivos pesados. Puedes usar Windows y Linux lado a lado.

Cómo instalar WSL2

Primero, activa el Subsitema de Windows para la opción Linux en las configuraciones.

Ve al inicio. Busca "Turn Windows features on or off".

Verifica la opción "Windows Subsystem for Linux" si ya no está.

Checking the option "Windows Subsystem for Linux" in Windows features

Luego, abre tu línea de comandos y provee los comandos de instalación.

Abre la terminal como un administrador:

Running command prompt as an admin by right clicking the app and choosing "run as admin£

Ejecuta el comando de abajo:

wsl --install

Esta es la salida:

Downloading progress of Ubuntu

Nota: Por defecto, Ubuntu será instalado.

Ubuntu installed by default using WSL
  • Una vez que la instalación está completa, necesitarás reiniciar tu máquina WIndows. Así que, reinicia tu máquina con Windows.

Después de reiniciar, verías una ventana así:

Window that shows after a restart

Una vez que la instalación de Ubuntu está completa, se te pedirá que ingreses tu nombre de usuario y la constraseña.

User prompted to enter a username and password

Y, ¡y eso es todo! Estás listo ya para usar Ubuntu.

Lanza Ubuntu buscando desde el menú de inicio.

Launching Ubuntu from the start menu

Y aquí tenemos tu instancia de Ubuntu lanzada.

Successful installation of Ubuntu using WSL

Opción 3: Usa a Máquina Virtual (VM)

Una máquina virtual (VM) es una emulación de software de un sistema de computación de Física. Te permite ejeuctar múltiples Sistemas Operativos y aplicaciones en una sola máquina física simultáneamente.

Puedes usar la Virtualización de Software tales como VirtualBox de Oracle o VMware para crear una máquina virtual que ejecuta Linux dentro de tu entorno de Windows. Esto te permite ejecutar Linux como un SIstema Operativo invitado junto a Windows.

El software VM provee opciones para asignar y gestionar los recursos hardware para cada VM, incluyendo núcles de CPU, memoria, espacio de disco, y ancho de banda de red. Puedes ajustar estas asignaciones basado en los requerimientos de los Sistemas Operativos invitados y las aplicaciones.

Aquí hay algunas de las opciones comúnes disponibles para la Virtualización:

Opción 4: Usa una Solución basado en el Navegador

Las soluciones basados en el Navegador son particularmente útiles para pruebas rápidas, aprender, o acceder a entornos de Linux desde dispositivos que no tienen Linux instalado.

Puedes usar los editores de código en líne o terminales basadas en web para acceder a Linux. Fíjate que usualmente no tienes privilegios de administrador en estos casos.

Editores de Código en línea

Los Editores de Código en línea con terminales de Linux incorporadas. Mientras que su propósito primario es codificar, también puedes utilizar la terminal de Linux para ejecutar comandos y realizar tareas.

Replit es un ejemplo de un editor de código en línea, donde puedes escribir tu código y acceder a la shell de Linux al mismo tiempo.

Running scripts and a bash shell in Replit

Terminales de Linux basados en Web

Las terminales de Linux en línea te permiten acceder a una interfaz de línea de comandos desde tu navegador. Estas terminalesproveen una interfaz basada en web a un shell de Linux, permitiéndote ejecutar comandos y trabajar con utilidades de Linux.

Un ejemploes JSLinux. La captura de abajo muestra un entorno de Linux listo para ser usado:

Using JSLinux to access Linux terminal

Opción 5: Usa una Solución basada en la Nube

En vez de ejecutar Linux directamente en tu máquina de Windows, puedes considerar usar entornos de Linux basados en la nube o Servidores Privados Virtuales (VPS), para acceder y trabajar con Linux remotamente.

Servicios como Amazon EC2, Microsoft Azure, o DigitalOcean proveen instancias de Linux a las que te puedes conectar desde tu computadora de Windows. Fíjate que algunos de estos servicios ofrecen planes gratuitos, pero no son usualmente gratis a la larga.

Parte 2: Introducción al Shell de Bash y Comandos de Sistema

2.1. Comenzando con el shell de Bash

Introducción al shell de bash

La línea de comandos de Linux es provisto por un programa llamado el shell. A través de los años, el programa shell ha evolucinado para atender varias opciones.

Distintos usuarios pueden ser configurados para usar distintos shells. Pero, la mayoría de los usuarios prefieren quedarse con su shell predeterminado actual. El shell predeterminado para muchos distros de Linux es el Bourne-Again Shell de GNU (bash). Bash es sucedido por el shell Bourne (sh).

Para saber tu shell actual, abre tu terminal e ingresa el siguiente comando:

echo $SHELL

Desglose del comando:

  • El comando echo se usa para imprimir en la terminal.
  • El $SHELL es una variable especial que contiene el nombre del shell actual.

En mi configuración, la salida es /bin/bash. Esto significa que estoy usando el shell bash.

# output
echo $SHELL
/bin/bash

Bash es muy poderoso ya que puede simplificar ciertas operaciones que son difíciles de lograr eficientemente con un GUI (o Interfaz de Usuario Gráfico). Recuerda que la mayoría de los servidores no tienen un GUI, y es mejor aprender a usar los poderosos de una interfza de línea de comandos (CLI).

Terminal vs Shell

Los términos "terminal" y "shell" son frecuentemente usado de forma intercambiable, pero se refieren a distitnas partes de la interfaz de línea de comandos.

La terminal es la interfaz que usas para interactuar con el shell. El shell es el intérprete de comandos que procesa y ejecuta tus comandos. Aprenderás más sobre los shells en la Parte 6 del manual.

¿Qué es un prompt?

Cuando un shell se usa interactivamente, muestra un $ cuando espera un comando del usuario. Este es el prompt del shell.

[username@host ~]$

Si el shell se está ejecutando como root (aprenderás más sobre el usuario root luego), el prompt se cambia a #.

[root@host ~]#

2.2. Estructura del Comando

Un comando es un programa que ejecuta una operación específica. Una vez que tienes acceso a la shell, puedes ingresar cualquier comando después del signo $ y ves la salida en la terminal.

Generalmente, los comandos de Linux sigue esta sintaxis:

command [options] [arguments]

Aquí está el desglose de la sintaxis de arriba:

  • command: Este es el nombre del comando que quieres ejecutar. ls (list - listar), cp (copy - copiar), y rm (remove - borrar) son comandos comúnes de Linux.
  • [options]: Opciones, o flags, son precedidos frecuentemente por un guión (-) o doble guiones (--), modifican el comportamiento del comando. Pueden cambiar cómo opera el comando. Por ejemplo, ls -a usa la opción -a para mostrar los archivos ocultos en la carpeta actual.
  • [arguments]: Los argumentos son las entradas para los comandos que uno requiere. Estos pueden ser nombres de archivos, nombres de usuario, u otros datos sobre los cuales el comando actuará. Por ejemplo, en el comando cat access.log, cat es el comando y access.log es la entrada. Como resultado, el comando cat muestra los contenidos del archivo access.log.

Las opciones y argumentos no son requeridos por todos los comandos. Algunos comandos pueden ser ejecutados sin ninguna opción o argumento, mientras que otros podrían requerir uno o ambos para que funcionen correctamente. Siempre puedes referirte al manual del comando para ver las opciones y los argumentos que soporta.

💡Consejo: Puedes ver el manual de un comando usando el comando man.

Puedes acceder a la página manual para ls con man ls, y te mostrará algo así:

5b1232a6-8c0b-4a97-86f0-9f15f2e14ed7

Las páginas manuales son una forma genial y rápida para acceder a la documentación. Recomiendo leer las páginas de man para los comandos que mas usas.

2.3. Comandos de Bash y Atajos de Teclado

Cuando estás en la terminal, puedes acelerar tus tareas usando atajos.

Aquí hay algunos de los atajos más comunes de la terminal:

Operación Atajo
Busca el comando previo Flecha arriba
Salta al principio de la palabra previa Ctrl+FlechaAbajo
Limpia los caracteres del cursor al final de la línea de comandos Ctrl+K
Completa los comandos, nombres de archivo, y opciones Presionando Tab
Salta al principio de la línea de comandos Ctrl+A
Muestra la lista de comandos previos history

2.4. Identificándote: El comando whoami

Puedes obtener el nombre de usuario con el que iniciaste sesión con el comando whoami. Este comando es útil cuando cambias entre distintos usuarios y quieres confirmar el usuario actual.

Justo después del signo $, escribe whoami y presiona enter.

whoami

Esta es la salida que obtuve.

zaira@zaira-ThinkPad:~$ whoami
zaira

Parte 3: Entendiendo tu Sistema de Linux

3.1. Descubriendo tu SO y Especificaciones

Imprimir información del sistema usando el comando uname

Puedes obtener información del sistema de forma detallada del comando uname.

Cuando provees la opción -a, imprime toda la información del sistema.

uname -a
# salida
Linux zaira 6.5.0-21-generic #21~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb  9 13:32:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

En la salida de arriba,

  • Linux: Indica el sistema operativo.
  • zaira: Representa el nombre del host de la máquina.
  • 6.5.0-21-generic #21~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 9 13:32:52 UTC 2: Provee información sobre la versión del kernel, fecha de la construcción, y algunos detalles adicionales.
  • x86_64 x86_64 x86_64: Indica la arquitectura del sistema.
  • GNU/Linux: Representa el tipo de sistema operativo.

Encontrar detalles de la arquitectura de la CPU usando el comando lscpu

El comando lscpu en Linux se usa para mostrar información sobre la arquitectura de la CPU. Cuando ejecutas lscpu en la terminal, provee detalles tales como:

  • La arquitectura de la CPU (por ejemplo, x86_64)
  • op-mode(s) de la CPU (por ejemplo, 32-bit, 64-bit)
  • Orden de Byte (por ejemplo, Little Endian)
  • CPU(s) (número de CPUs), y así sucesivamente

Intentémoslo:

lscpu
# salida
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         48 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  12
  On-line CPU(s) list:   0-11
Vendor ID:               AuthenticAMD
  Model name:            AMD Ryzen 5 5500U with Radeon Graphics
    Thread(s) per core:  2
    Core(s) per socket:  6
    Socket(s):           1
    Stepping:            1
    CPU max MHz:         4056.0000
    CPU min MHz:         400.0000

Eso fue mucha información, ¡pero útil también! Recuerda que siempre puedes ir viendo información relevante usando argumentos específicos. Ve el manual del comando con man lscpu.

Parte 4: Manejando archivos desde la Línea de Comandos

4.1. La Jerarquía del sistema de archivos de Linux

Todos los archivos en Linux son almacenados en un sistema de archivos. Sigue una estructura tipo árbol invertido porque la raíz está en la parte superior.

El  / es la carpeta raíz y el punto de comienzo del sistema de archivos. La carpeta raíz contiene todas las otras carpetas y archivos en el sistema. El caracter / también sirve como una carpeta separadora entre los nombres de rutas. Por ejemplo, /home/alice forma una ruta completa.

La imagen de abajo muestra la jerarquía completa del sistema de archivos. Cada carpeta sirve un propósito específico.

Fíjate que esta no es una lista exhaustiva y distintas distribuciones podría tener distintas configuraciones.

Linux file system hierarchy

Aquí hay una tabla que muestra el propósito de cada carpeta:

Ubicación Propósito
/bin Binarios de comandos esenciales
/boot Archivos estáticos del cargador de arranque (boot loader), necesario para comenzar el proceso de incio.
/etc Configuración de sistema específica del host
/home Carpetas personales del usuario
/root Carpeta personal para el usuario root administrativo
/lib Librerías compartidas y módulos del kernel esenciales
/mnt Punto de montaje para montar un sistema de archivos de forma temporal
/opt Paquetes de software de aplicación complementarios
/usr Software y librerías compartidas instalados
/var Datos de variables que es también persistente entre los arranques
/tmp Archivos temporarios que son accessibles a todos los usuarios

💡 Consejo: Puedes aprender más sobre el sistema de archivos usando el comando man hier.

Puedes ver tu sistema de archivos usando el comando tree -d -L 1. Puedes modificar el argumento -L para cambiar la profundidad del árbol.

tree -d -L 1
# salida
.
├── bin -> usr/bin
├── boot
├── cdrom
├── data
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib32 -> usr/lib32
├── lib64 -> usr/lib64
├── libx32 -> usr/libx32
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── snap
├── srv
├── sys
├── tmp
├── usr
└── var

25 carpetas

Esta lista no es exhaustiva y distintas distribuciones y sistemas podrían ser configurados de forma distinta.

Ruta absoluta vs ruta relativa

La ruta absoluta es la ruta completa de la carpeta raíz al archivo o a la carpeta. Siempre comienza con un /. Por ejemplo, /home/john/documents.

La ruta relativa, por otro lado, es la ruta desde la carpeta actual al archivo de destino o a la carpeta. No comienza con un /. Por ejemplo, documents/work/project.

Localizando tu carpeta actual usando el comando pwd

Es fácil perder tu camino en el sistema de archivos de Linux, especialmente si eres nuevo en la línea de comandos. Puedes localizar tu carpeta actual usando el comando pwd.

Aquí hay un ejemplo:

pwd
# output
/home/zaira/scripts/python/free-mem.py

Cambiando carpetas usando el comando cd

El comando para cambiar carpetas es cd y significa "cambiar carpeta - change directory en inglés". Puedes usar el comando cd para navegar hacia otra carpeta diferente.

Puedes usar una ruta relativa o una ruta absoluta.

Por ejemplo, si quieres navegar la estructura de archivos de abajo (siguiendo las líneas rojas):

Example file structure

y estás en "home", el comando sería así:

cd home/bob/documents/work/project

Otros atajos de cd usado comúnmente son:

Comando Descripción
cd .. Regresar una carpeta
cd ../.. Regresar dos carpetas
cd o cd ~ Regresar a la carpeta personal
cd - Regresar a la ruta previa

4.3. Manejando archivos y carpetas

Cuando se trabaja con archivos y carpetas, podrías querer copiar, mover, quitar, y crear archivos y carpetas nuevas. Aquí hay algunos comandos que te pueden ayudar con eso.

💡Consejo: Puedes diferenciar entre un archivo y una carpeta mirando la primera letra en la salida de ls -l. Un '-' representa un archivo y un 'd' representa una carpeta.

"d" represents a folder

Creando nuevas carpetas usando el comando mkdir

Puedes crear una carpeta vacía usando el comando mkdir.

# creates an empty directory named "foo" in the current folder
mkdir foo

También puedes crear carpetas recursivamente usando la opción -p.

mkdir -p tools/index/helper-scripts
# output of tree
.
└── tools
    └── index
        └── helper-scripts

3 directories, 0 files

Creando nuevos archivos usando el comando touch

El comando touch crea un archivo vacío. Puedes usarlo así:

# creates empty file "file.txt" in the current folder
touch file.txt

Los nombres del archivo pueden ser encadenados si quieres crear múltiples archivos en un solo comando.

# creates empty files "file1.txt", "file2.txt", and "file3.txt" in the current folder

touch file1.txt file2.txt file3.txt

Eliminando archivos y carpetas usando el comando rm y rmdir

Puedes usar el comando rm para eliminar ambos archivos y carpetas no vacías.

Comando Descripción
rm archivo.txt Elimina el archivo archivo.txt
rm -r dir Elimina la carpeta dir y su contenido
rm -f archivo.txt Elimina el archivo archivo.txt sin mostrar un mensaje de confirmación
rmdir carpeta Elimina una carpeta vacía

🛑 Fíjate que deberías usar el argumento -f con cuidado ya que no te preguntará antes de eliminar un archivo. También, ten cuidado cuando ejecutas comandos rm en la carpeta root ya que podría resultar en eliminar archivos importantes de sistema.

Copiando archivos usando el comando cp

Para copiar archivos en Linux, usa el comando cp.

  • Sintaxis para copiar archivos:cp source_file destination_of_file

Este comando copia un archivo llamado file1.txt a una nueva ubicación del archivo /home/adam/logs.

cp file1.txt /home/adam/logs

El comando cp también crea una copia de un archivo con el nombre provisto.

Este comando copia un archivo llamado file1.txt a otro archivo llamado file2.txt en la misma carpeta.

cp file1.txt file2.txt

Moviendo y renombrando archivos y carpetas usando el comando mv

El comando mv se usa para mover archivos y carpetas de una carpeta a otra.

Sintaxis para mover archivos: mv source_file destination_directory

Ejemplo: Mover un archivo llamado file1.txt a una carpeta llamada backup:

mv file1.txt backup/

Para mover una carpeta y sus contenidos:

mv dir1/ backup/

Renombrando archivos y carpetas en Linux también se hace con el comando mv.

Sintaxis para renombrar archivos: mv old_name new_name

Ejemplo: Renombrar un archivo de file1.txt a file2.txt:

mv file1.txt file2.txt

Renombrar una carpeta de dir1 a dir2:

mv dir1 dir2

4.4. Localizando archivos y carpetas usando el comando find

El comando find te permite buscar eficientemente archivos, carpetas, y un caracter y dispositivos de bloque.

Abajo está la sintaxis del comando find:

find /path/ -type f -name file-to-search

Donde,

  • /path es la ruta donde el archivo se espera ser encontrado. Este es el punto de comienzo para buscar archivos. La ruta también pueder ser / o . el cual representa la raíz y la carpeta actual, respectivamente.
  • -type representa los descriptores del archivo. Pueden ser cualquiera de lo de abajo: fArchivo regular tales como archivos de texto, imágenes, y archivos ocultos. dCarpeta. Estosson las carpetas bajo consideración. lEnlace Simbólico. Los enlaces simbólicos apunta a archivos y son similares a atajos. cDispositivos de Caracteres. Archivos que se usan para acceder a dispositivos de carecteres se llaman archivos de dispositivo de caracter. Los drivers se comunican con dispositivos de caracteres enviando y recibiendo caracteres individuales (bytes, octetoss). Ejemplos incluyen teclados, tarjetas de sonido, y el ratón. bDispositivos de Bloque. Archivos que se usan para acceder a dispositivos de bloque se llaman archivos de dipositivos de bloque. Los drivers se comunican con dispositivos de bloque enviando y recibiendo bloques enteros de datos. Ejemplos incluyen USB y CD-ROM.
  • -name es el nombre del tipo de archivo que quieres buscar.

Cómo buscar archivos por nombre o extensión

Supón que necesitamos encontrar archivos que contienen "style" en sus nombres. Usaremos este comando

find . -type f -name "style*"
#output
./style.css
./styles.css

Ahora digamos que queremos encontrar archivos con una extensión particular como .html. Modificaremos el comando así:

find . -type f -name "*.html"
# output
./services.html
./blob.html
./index.html

Cómo buscar archivos ocultos

Un punto al comienzo del nombre de archivo representa archivos ocultos. Son ocultos normalmente pero pueden ser vistos con ls -a en la carpeta actual.

Podemos modificar el comando find como se muestra abajo para buscar archivos ocultos:

find . -type f -name ".*"

Listar y encontrar archivos ocultos

ls -la
# contenido de las carpetas
total 5
drwxrwxr-x  2 zaira zaira 4096 Mar 26 14:17 .
drwxr-x--- 61 zaira zaira 4096 Mar 26 14:12 ..
-rw-rw-r--  1 zaira zaira    0 Mar 26 14:17 .bash_history
-rw-rw-r--  1 zaira zaira    0 Mar 26 14:17 .bash_logout
-rw-rw-r--  1 zaira zaira    0 Mar 26 14:17 .bashrc

find . -type f -name ".*"
# salida de find
./.bash_logout
./.bashrc
./.bash_history

Arriba puedes ver una lista de archivos ocultos en mi carpeta home.

Cómo buscar archivos log y archivos de configuración

Los archivos logs usualmente tienen la extensión .log, y podemos encontrarlos así:

 find . -type f -name "*.log"

De forma similar, podemos buscar archivos de configuración de esta forma:

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

Cómo buscar otros archivos por tipo

Podemos buscarpor archivos de bloque de caracteres proveyendo c a -type:

find / -type c

De forma similar, podemos encontrar archivos de bloque de dispositivos usando b:

find / -type b

Cómo buscar carpetas

En el ejemplo de abajo, encontramos las carpetas usando el argumento -type d.

ls -l
# lista el contenido de las carpetas
drwxrwxr-x 2 zaira zaira 4096 Mar 26 14:22 hosts
-rw-rw-r-- 1 zaira zaira    0 Mar 26 14:23 hosts.txt
drwxrwxr-x 2 zaira zaira 4096 Mar 26 14:22 images
drwxrwxr-x 2 zaira zaira 4096 Mar 26 14:23 style
drwxrwxr-x 2 zaira zaira 4096 Mar 26 14:22 webp 

find . -type d 
# salida de find mostrando carpetas
.
./webp
./images
./style
./hosts

Cómo buscar archivos por tamaño

Un uso increíblemente útil del comando find es listar archivos basados en un tamaño particular.

find / -size +250M

Aquí, estamos listando archivos cuyos tamaños exceden los 250MB.

Otras unidades incluyen:

  • G: GigaBytes.
  • M: MegaBytes.
  • K: KiloBytes
  • c : bytes.

Sólo reemplaza con la unidad relevante.

find <directory> -type f -size +N<Unit Type>

Cómo buscar archivos por tiempo de modificación

Usando el argumento -mtime, puedes filtrar archivos y carpetas basado en el tiempo de modificación.

find /path -name "*.txt" -mtime -10

Por ejemplo,

  • -mtime +10 significa que estás buscando un archivo que se modificó hace 10 días.
  • -mtime -10 significa menos de 10 días.
  • -mtime 10 si te salteas + o – significa exactamente 10 días.

4.5. Comandos Básicos para ver archivos

Concatena y muestra archivos usando el comando cat

El comando cat en Linux se usa para mostrar los contenidos de un archivo. También puede ser usado para concatenar y crear nuevos archivos.

Aquí está la sintaxis básica del comando cat:

cat [opciones] [archivo]

La forma más simple de usar cat es sin ninguna opción o argumento. Esto mostrará los contenidos del archivo en la terminal.

Por ejemplo, si quieres mostrar los contenidos de un archivo llamado file.txt, puedes usar el siguiente comando:

cat file.txt

Esto mostrará todos los contenidos del archivo en la termina de una sola vez.

Ver archivos de texto de forma interactiva usando less y more

Mientras que cat muestra todo el archivo de una sola vez, less y more te permite ver los contenidos de un archivo de forma interactiva. Esto es útil cuando quieres desplazarte a través de un archivo grande o buscar por contenido específico.

La sintaxis del comando less es:

less [opciones] [archivo]

El comando more es similar a less pero tiene menos características. Se usa para mostrar los contenidos de un archivo en una pantalla a la vez.

La sintaxis del comando more es:

more [opciones] [archivo]

Para ambos comandos, puedes usar el la barra de espacio para desplazarte a una página abajo, la tecla Enter para desplazarte una línea abajo, y la tecla q para salir del visualizador.

Para moverte hacia atrás puedes usar la tecla b, y para moverte hacia adelante puedes usar la tecla f.

Mostrando la última parte de los archivos usando tail

A veces podrías necesitar ver solo las últimas líneas de un archivo en vez de todo el archivo. El comando tail en Linux se usa para mostrar la última parte de un archivo.

Por ejemplo, tail file.txt mostrará las últimas 10 líneas del archivo file.txt por defecto.

Si quieres mostrar un número distinto de líneas, puedes usar la opción -n seguido del número de líneas que quieres mostrar.

# Muestra las últimas 50 líneas del archivo file.txt
tail -n 50 file.txt

💡Consejo: Otro uso de tail es su opción inmediata (-f). Esta opción te permite ver los contenidos de un archivo a medida que están siendo escritos. Esto es una utilidad útil para ver y monitorear archivos log en tiempo real.

Mostrar el comienzo de los archivos usando head

Así como tail muestra la última parte de un archivo, puedes usar el comando head en Linux para mostrar el inicio de un archivo.

Por ejemplo, head file.txt mostrará las 10 primera líneas del archivo file.txt por defecto.

Para cambiar el número de líneas mostradas, puedes usar la opción -n seguido del número de líneas que quieres mostrar.

Contando palabras, líneas, y caracteres usando wc

Puedes contar palabras, líneas y caracteres en un archivo usando el comando wc.

Por ejemplo, ejecutando wc syslog.log me dio la siguiente salida:

1669 9623 64367 syslog.log

En la salida de arriba,

  • 1669 representa el número de líneas en el archivo syslog.log.
  • 9623 representa el número de palabras en el archivo syslog.log.
  • 64367 representa el número de caracteres en el archivo syslog.log.

Así que, el comando wc syslog.log contó 1669 líneas 9623 palabras, y 64367 caracteres en el archivo syslog.log.

Comparando archivo línea por línea usando diff

Comparando y encontrando diferencias entre dos archivos es una tarea común en Linux. Puedes comparar dos archivos justo en la línea de comandos usando el comando diff.

La sintaxis básica del comando diff es:

diff [opciones] archivo1 archivo2

Aquí hay dos archivos, hello.py y also-hello.py, que compararemos usando el comando diff:

# contenido de hello.py

def greet(name):
    return f"Hola, {name}!"

user = input("Ingresa tu nombre: ")
print(greet(user))
# contenido de also-hello.py

more also-hello.py
def greet(name):
    return fHola, {name}!

user = input(Ingresa tu nombre: )
print(greet(user))
print("¡Un placer en conocerte!")
  1. Verifica si los archivos son similares o no.
diff -q hello.py also-hello.py
# Salida
Files hello.py and also-hello.py differ

2.   Ve cómo los archivos difieren. Para eso, puedes usar el argumento -u para ver una salida unificada:

diff -u hello.py also-hello.py
--- hello.py    2024-05-24 18:31:29.891690478 +0500
+++ also-hello.py    2024-05-24 18:32:17.207921795 +0500
@@ -3,4 +3,5 @@

 user = input(Ingresa tu nombre: )
 print(greet(user))
+print("Un placer en conocerte")

En la salida de arriba:

  • --- hello.py 2024-05-24 18:31:29.891690478 +0500 indica el archivo siendo comparado y su marca de tiempo.
  • +++ also-hello.py 2024-05-24 18:32:17.207921795 +0500 indica el otro archivo siendo comparado y su marca de tiempo.
  • @@ -3,4 +3,5 @@ muestra los número de línea donde los cambios ocurren. En estecaos, indica que las líneas 3 a 4 en el archivo original ha cambiado a las líneas 3 a 5 en el archivo modificado.
  • user = input(Ingresa tu nombre: ) es una línea del archivo original.
  • print(greet(user)) es otra línea del archivo original.
  • print("Un placer en conocerte") es la línea adicional en el archivo modificado.

3.   Para ver el diff en un formato lado a lado, puedes usar el argumento -y:

diff -y hello.py also-hello.py
# Salida
def greet(name):                        def greet(name):
    return fHola, {name}!                        return fHola, {name}!

user = input(Ingresa tu nombre: )                    user = input(Enter your name: )
print(greet(user))                        print(greet(user))
                                        >    print("Un placer en conocerte")

En la salida:

  • Las líneas que están en ambos archivos se muestran lado a lado.
  • Las líneas que son distintas se muestran con un símbolo > indicando que la línea está presente solamente en uno de los archivos.

Parte 5: Lo Esencial sobre Edición de Texto en Linux

Las habilidades de edición de texto usando la línea de comandos son una de las habilidades más cruciales en Linux. En esta sección, aprenderás cómo usar dos editores de textos populares en Linux: Vim y Nano.

Te sugiero que domines cualquier editor de texto de tu gusto y apegarte a él. Te ahorrará tiempo y te hará más productivo. Vim y nano son opciones seguras ya que están presentes en la mayoría de las distribuciones de Linux.

5.1. Dominando Vim: La Guía Completa

Introducción a Vim

Vim es una herramienta de edición de texto popular para la línea de comandos. Vim tiene sus ventajas: es poderoso, personalizable, y rápido. Aquí hay algunas razones de por qué deberías considerar aprender Vim:

  • La mayoría de los servidores son accedidos a través de un CLI, así que en administración de sistemas, no es necesario que tengas los lujos de un GUI. Pero Vim te respalda – siempre estarás allí.
  • Vim usa un enfoque centrado al teclado, ya que está diseñado para ser usado sin un ratón, lo cual puede acelerar significativamente las tareas de edición una vez que has aprendido los atajos de teclado. Esto también lo hace más rápido que las herramientas GUI.
  • Algunas utilidades de Linux, por ejemplo edición de cron jobs, funcionan en el mismo formato de edición como Vim.
  • Vim es apropiado para todos – usuarios principiantes y avanzados. Vim suporta búsquedas de cadena complejas, resaltación de búsquedas, y mucho más. A través de los plugins, Vim provee capacidades extendidas para los desarrolladores y administradores de sistema que incluyen completación de código, resaltación de sintaxis, gestión de archivos, control de versiones, y más.

Vim tiene dos variaciones: Vim (vim) y Vim pequeño (vi). Vim pequeño es una versión más pequeña de Vim que carece de algunas características de Vim.

Cómo comenzar usando vim

Comienza usando Vim con este comando:

vim your-file.txt

your-file.txt puede ser un nuevo archivo o un archivo existente que quieres editar.

A principios del CLI, los teclados no tenían teclas de flecha. Por lo tanto, la navegación se hacía usando el conjunto de teclas disponibles, hjkl siendo uno de ellos.

Siendo centrado al teclado, usando las teclas hjkl pueden acelerar inmensamente las tareas de edición de texto.

Nota: aunque las teclas de flecha funcionan bien totalmente, todavías puedes experimentar con las teclas hjkl para navegar. Algunas personas encuentran esta forma de navegar eficiente.

💡Consejo: Para recordar la secuencia de hjkl, usa esto: hang back, jump down, kick up, leap forward (quedarse atrás, saltar hacia abajo, patear, saltar hacia adelante).

hjkl navigation guide

Los tres modos de Vim

Necesitas conocer los 3 modos de operando de Vim y cómo cambiarlos. Las pulsaciones de teclas se comportan de forma distinta en cada modo de comando. Los tres modos son los siguientes:

  1. Modo comando.
  2. Modo edición.
  3. Modo Visual.

Modo Comando. Cuando comienzas con Vim, llegas al modo comando por defecto. Este modo te permite acceder a otros módulos.

⚠ Para cambiar a otros modos, necesitas estar presente en el modo comando primero.

Modo edición

Este modo te permite hacer cambios al archivo. Para entrar el modo edición, presiona I mientras estás en modo comando. Fíjate el conmutador '-- INSERT' al final de la pantalla.

Insert mode in Vim

Modo visual

Este modo te permite trabajar en un solo caracter, un bloque de texto, o líneas de texto. Vamos a descomponerlo en pasos sencillos. Recuerda, usa las combinaciones de abajo cuando estés en modo comando.

  • Shift + V → Selecciona múltiples líneas.
  • Ctrl + V → Modo bloque.
  • V → Mode caracter.

El modo visual viene bien cuando necesitas copiar y pegar o editar líneas en masa.

Selectind text using visual mode

Modo comando extendido.

El modo comando extendido te permite realizar operaciones avanzadas como buscar, establecer números de líneas, y resaltar texto. Cubriremos el modo extendido en la próxima sección.

¿Cómo mantener el rumbo? Si te olvidas de tu modo actual, solo presiona ESC dos veces y estarás de vuelta en Modo Comando.

Editando eficientemente en Vim: Copiar/pegar y buscar

1. Cómo copiar y pegar en Vim

Copiar-pegar es conocido como 'yank' y 'put' en términos de Linux. Para copiar-pegar, sigue estos pasos:

  • Selecciona texto en modo visual.
  • Presiona 'y' para copiar/ yank.
  • Mueve tu cursor a la posición requerida y presiona 'p'.

2. Cómo buscar texto en Vim

Cualquier serie de cadenas puede ser buscado con Vim usando el / en modo comando. Para buscar, usa /string-to-match.

En el modo comando, escribe :set hls y presiona enter. Busca usando /string-to-match. Esto resaltará las búsquedas.

Busqueamos unas pocas cadenas:

Highlighting searches in Vim

3. Cómo salir de Vim

Primero, pásate a modo comando (presionando escape dos veces) y luego usa estos argumentos:

  • Salir sin guardar → :q!
  • Salir y guardar → :wq!

Atajos en Vim: Haciendo la edición más rápido

Nota: todos estos atajos funcionan solamente en el modo comando.

  • Navegación básica
  • h: Mover a la izquierda
  • j: Mover hacia abajo
  • k: Mover hacia arriba
  • l: Mover a la derecha
  • 0: Mover al principio de la línea
  • $: Mover al final de la línea
  • gg: Mover al principio del archivo
  • G: Mover al final del archivo
  • Ctrl+d: Mover media página hacia abajo
  • Ctrl+u: Mover media página hacia arriba
  • Editando
  • i: Ingresa modo insertar antes del cursor
  • I: Ingresa el modo instertar al principio de la línea
  • a: Ingresa el modo insertar después del cursor
  • A: Ingresa el modo insertar al final de la línea
  • o: Abre una nueva línea debajo de la línea actual e ingresa el modo insertar
  • O: Abre una nueva línea arriba de la línea actual e ingresa el modo insertar
  • x: Elimina el caracter debajo del cursor
  • dd: Elimina la línea actual
  • yy: Yank (copia) la línea actual (usa esto en modo visual)
  • p: Pegar debajo del cursor
  • P: Pegar arriba del cursor
  • Buscando y Reemplazando
  • /: Buscar un patrón el cual te llevará a la próxima ocurriencia
  • ?: Buscar un patrón que te llevará a la ocurrencia previa
  • n: Repite la última búsqueda en la misma dirección
  • N: Repite la última búsqueda en la dirección opuesta
  • :%s/old/new/g: Reemplaza todas las ocurrencias de old con new en el archivo
  • Saliendo
  • :w: Guarda el archivo pero no sale
  • :q: Sale de Vim (falla si hay cambios no guardados)
  • :wq or :x: Guardar y sale
  • :q!: Sale sin guardar
  • Múltiples Ventanas
  • :split or :sp: Divide la ventana horizontalmente
  • :vsplit or :vsp: Divide la ventana verticalmente
  • Ctrl+w followed by h/j/k/l: Navega entre ventanas divididas

5.2. Dominando Nano

Comenzando con Nano: El editor de texto amigable

Nano es un editor de texto amigable que es fácil de usar y es perfecto para los principiantes. Está pre-instalado en la mayoría de las distribuciones de Linux.

Para crear un nuevo archivo usando Nano, usa el siguiente comando:

nano

Para empezar a editar un archivo existente con Nano, usa el siguiente comando:

nano filename

Lista de combinaciones de tecla en Nano

Estudiemos las combinaciones de tecla más importantes en Nano. Usará las combinaciones de tecla para realizar varias operaciones como guardar, salir, copiar, pegar, y más.

Escribir a un archivo y guardar

Una vez que abres Nano usando el comando nano, puedes comenzar con escribir texto. Para guardar el archivo, presiona Ctrl+O. Te aparecerá una ventana para que ingreses el nombre del archivo. Presiona Enter para guardar el archivo.

Salir de nano

Puedes salir de Nano presionando Ctrl+X. Si tienes cambios no guardados, Nano te mostrará una ventana para guardar los cambios antes de salir.

Copiar y pegar

Para seleccionar una región, usa ALT+A. Un marcador aparecerá. Usa las flechas para seleccionar el texto. Una vez seleccionado, sale del marcador con ALT+^.

Para copiar el texto seleccionado, presiona Ctrl+K. Para guardar el texto copiado, presiona Ctrl+U.

Cortar y pegar

Selecciona la región con ALT+A. Una vez seleccionado, corta el texto con Ctrl+K. Para pegar el texto cortado, presiona Ctrl+U.

Navegación

Usa Alt \ para moverte al principio del archivo.

Usa Alt / para moverte al final del archivo.

Viendo números de línea

Cuando abres un archivo con nano -l filename, puedes ver los números de línea en el lado izquierdo del archivo.

Buscando

Puedes buscar un número de línea específico con ALt + G. Ingresa el número de línea al prompt y presiona Enter.

También puedes iniciar una búsqueda de una cadena con CTRL + W y presiona Enter. Si quieres buscar hacia atrás, puedes presionar Alt + W después de iniciar la búsqueda con Ctrl + W.

Resumen de combinaciones de tecla en Nano

  • General
  • Ctrl+X: Sale de Nano (sale una ventana para guarda si se hacen cambios)
  • Ctrl+O: Guarda el archivo
  • Ctrl+R: Lee un archivo en un archivo actual
  • Ctrl+G: Muestra el texto de ayuda
  • Editando
  • Ctrl+K: Corta la línea actual y lo almacena en el cutbuffer
  • Ctrl+U: Guarda los contenidos del cutbuffer en la línea actual
  • Alt+6: Copia la línea actual y lo almacena en el cutbuffer
  • Ctrl+J: Justifica el párrafo actual
  • Navigación
  • Ctrl+A: Se mueve al principio de la línea
  • Ctrl+E: Se mueve al final de la línea
  • Ctrl+C: Muestra el número de línea actual e información del archivo
  • Ctrl+_ (Ctrl+Shift+-): Va a un número de línea específica (y opcionalmente, una columna)
  • Ctrl+Y: Se desplaza una página arriba
  • Ctrl+V: Se desplaza una página abajo
  • Buscar y Reemplazar
  • Ctrl+W: Buscar una cadena (luego Enter para búscar nuevamente)
  • Alt+W: Repite la última búsqueda pero en la dirección opuesta
  • Ctrl+\: Busca y reemplaza
  • Misceláneos
  • Ctrl+T: Invoca el corrector ortográfico, si está disponible
  • Ctrl+D: Elimina el caracter debajo del cursor (no lo corta)
  • Ctrl+L: Refresca (redibuja) la ventana actual
  • Alt+U: Deshace la última operación
  • Alt+E: Rehace la última operación sin terminar

Parte 6: La Programación en Bash

6.1. Definición de los scripts de Bash

Un script de Bash es un archivo que contiene una secuencia de comandos que son ejecutados por el programa de bash línea por línea. Ter permite realizar una serie de acciones, tales como navegar a una carpeta específica, crear una carpeta, y lanzar un proceso usando la línea de comandos.

Al guardar comandos en un script, puedes repetir la misma secuencia de pasos múltiples veces y ejecutarlos al correr el script.

6.2. Ventajas de los scripts de Bash

La programación en Bash es una herramienta poderosa y versátil para las tareas de administración de sistemas, gestionar los recursos del sistema, y realizar otras tareas de rutinas en sistemas Unix/Linux.

Algunas ventajas de la programación de scripts son:

  • Automatización: Los scripts de Shell te permiten automatizar tareas y procesos repetitivos, ahorrando tiempo y reducir el riesgo de errores que pueden ocurrir con la ejecución manual.
  • Portabilidad: Los scripts de Shell pueden ser ejecutados en varias plataformas y sistemas operativos, incluyendo Unix, Linux, macOS, e inclusive Windows a través del uso de emuladores o máquinas virtuales.
  • Flexibilidad: Los scripts de Shell son bastantes personalizables y pueden ser fácilmente modificados para adaptarse a requerimientos específicos. También pueden ser combinados con otros lenguajes de programación o utilidades para crear scripts más poderosos.
  • Accesibilidad: Los scripts de Shell son fáciles de escribir y no requieren ninguna herramienta o software especial. Pueden ser editados usando cualquier editor de texto, y la mayoría de sistemas operativos tienen un intérprete de shell incorporado.
  • Integración: Los scripts de Shell pueden ser integrados con otras herramientas y aplicaciones, tales como bases de datos, servidores web, y servicios de la nube, permitiendo automatización más complejo y tareas de gestión de sistema.
  • Depuración: Los scripts de Shell son fáciles de depurar, y la mayoría de los shells tienen herramientas de depuración y reporte de errores incorporados que pueden ayudar a identificar y arreglar problemas rápidamente.

6.3. Vista general del Shell de Bash y la Interfaz de Línea de Comandos

Los términos "shell" y "bash" son frecuentemente usados de forma intercambiable. Pero hay una diferencia sutil entre los dos.

El término "shell" se refiere a un programa que provee una interfaz de línea de comandos para interactuar con un sistema operativo. Bash (Bourne-Again SHell) es uno de los shell de Unix/Linux más usado comúnmente y es la shell predeterminada en muchas distribuciones de Linux.

Hasta ahora, los comandos que has estado haciendo eran básicamente ingresados en un "shell".

Aunque Bash es un tipo de shell, hay otras shells disponibles también, tales como Korn shell (ksh), C shell (csh), y Z shell (zsh). Cada shell tiene su propia sintaxis y conjunto de características, pero todos comparten el mismo propósito común de proveer una interfaz de línea de comandos para interactuar con el sistema operativo.

Puedes determinar tu tipo de shell usando el comando ps:

ps
# output:

    PID TTY          TIME CMD
  20506 pts/0    00:00:00 bash <--- the shell type
  20931 pts/0    00:00:00 ps

En resumen, mientras que "shell" es un término amplio que se refiere a cualquier programa que provee una interfaz de línea de comandos, "Bash" es un tipo específico de shell que es ampliamente usado en sistemas de Unix/Linux.

Nota: En esta sección, estaremos usando el shell "bash".

6.4. Cómo crear y ejecutar scripts de Bash

Convenciones de nombramiento de Script

Por convención de nombramiento, los scripts de Bash terminan con .sh. Sin embargo, los scripts de bash se pueden ejecutar perfectamente sin la extensión sh.

Agregando el Shebang

Los scripts de Bash comienzan con un shebang. El shebang es una combinación de bash # y bang ! seguido de la ruta del shell bash. Esta es la primer línea del script. El shebang le dice al shell para ejecutarlo a través del shell bash. Shebang es simplemente una ruta absoluta al intérprete del bash.

Abajo hay un ejemplo de la declaración del shebang.

#!/bin/bash

Puedes encontrar tu ruta del shell bash (lo cual puede variar de lo de arriba) usando el comando:

which bash

Creando tu primer script de bash

Nuestro primer script muesta un mensaje al usuario que ingrese una ruta. En retorno, sus contenidos serán listados.

Crea un archivo llamado run_all.sh usando cualquier editor de tu preferencia.

vim run_all.sh

Agrega los siguientes comandos en tu archivo y guárdalo:

#!/bin/bash
echo "Hoy es " `date`

echo -e "\ningresa la ruta a la carpeta"
read the_path

echo -e "\n tu ruta tiene los siguientes archivos y carpetas: "
ls $the_path

Echemos un vistazo más profundamente al script línea por línea. Estoy mostrando el mismo script nuevamente, pero esta vez con números de líneas.

  1 #!/bin/bash
  2 echo "Hoy es " `date`
  3
  4 echo -e "\ningresa la ruta a la carpeta"
  5 read the_path
  6
  7 echo -e "\n tu ruta tiene los siguientes archivos y carpetas: "
  8 ls $the_path
  • Línea #1: El shebang (#!/bin/bash) apunta a la ruta del shell bash.
  • Línea #2: El comando echo muestra la fecha y el tiempo actual en la terminal. Fíjate que el date está en comillas invertidas.
  • Línea #4: Queremos que el usuario ingrese una ruta válida.
  • Línea #5: El comando read lee la entrada y lo almacena en la variable the_path.
  • Línea #8: El comando ls toma la variable con la ruta almacenada y muestra los archivos y las carpetas actuales.

Ejecutando el script de bash

Para hacer que el script sea ejecutable, asigna permisos de ejecución a tu usuario usando este comando:

chmod u+x run_all.sh

Aquí,

  • chmod modifica la propiedad de un archivo para el usuario actual :u.
  • +x agrega los derechos de ejecución al usuario actual. Esto significa que el usuario quien es el propietario ahora puede ejecutar el script.
  • run_all.sh es el archivo que deseamos ejecutar.

Puedes ejecutar el script usando cualquier de los métodos mencionados:

  • sh run_all.sh
  • bash run_all.sh
  • ./run_all.sh

Veámoslo la ejecución en acción 🚀

Running a bash script

6.5. Lo básico de la Programación en Bash

Comentarios en la programación de bash

Los comentarios comienzan con un # en la programación de bash. Esto significa que cualquier línea que comience con un # es un comentario y será ignorado por el intérprete.

Los comentarios son muy útiles en la documentación del código, y es una buena práctica agregarlos para ayudar a otros que entiendan el código.

Estos son ejemplos de comentarios:

# Este es un comentario de ejemplo
# Estas dos líneas serán ignorados por el intérprete

Variables y tipos de datos en Bash

Las variables te permiten almacenar datos. Puedes usar variables para leer, acceder, y manipular datos en tu script.

No hay tipos de datos en Bash. En Bash, una variable es capaz de almacenar valores numéricos, caracteres individuales, o cadenas de caracteres.

En Bash, puedes usar y establecer los valores de variable en las siguientes formas:

  1. Asignar el valor directamente:
country=Netherlands

2.  Asignar el valor basado en la salida obtenido de un programa o comando, usando substitución de comando. Fíjate que $ es requerido para acceder al valor de una variable existente.

same_country=$country

Esto asigna el valor de country a la nueva variable same_country.

Para acceder el valor de la variable, adjunta $ al nombre de la variable.

country=Netherlands
echo $country
# salida
Netherlands
new_country=$country
echo $new_country
# salida
Netherlands

Arriba, puedes ver un ejemplo de asignamiento e impresión de valores de variable.

Convenciones de nombramiento de Variable

En la programación de Bash, lo siguiente son convenciones de nombramiento de variable:

  1. Los nombres de variables deberían comenzar con una letra o un guión bajo (_).
  2. Los nombres de variables pueden contener letras, números, y guiones bajos (_).
  3. Los nombres de variables son distinguen mayúsculas y minúsculas.
  4. Los nombres de variables no deberían contener espacios o caracteres especiales.
  5. Una nombres descriptivos que reflejan el propósito de la variable.
  6. Evita usar palabras claves reservadas, tales como if, then, else, fi, y así sucesivamente como nombres de variables.

Aquí hay algunos ejemplos de nombres de variables válidos en Bash:

name
count
_var
myVar
MY_VAR

Y aquí hay algunos ejemplos de nombres de variables inválidos:

# Nombres de variables inválidos

2ndvar (nombre de variable comienza con un número)
my var (nombre de variable contiene un espacio)
my-var (nombre de variable contains un guión)

Siguiendo estas convenciones de nombramiento ayudan en hacer que los scripts de Bash sean más legibles y más fáciles de mantener.

Entradas y salidas en scripts de Bash

Recopilación de entradas

En esta sección, discutiremos algunos métodos para proveer entradas a nuestros scripts.

  1. Leer las entradas de usuario y almacenarlos en una variable

Podemos leer la entrada de usuario usando el comando read.

#!/bin/bash
echo "What's your name?"
read entered_name
echo -e "\nWelcome to bash tutorial" $entered_name
Reading the name from a script

2.   Leer de un archivo

Este código lee cada línea de un archivo llamado input.txt y lo imprime a la terminal. Estudiaremos los bucles while más tarde en esta sección.

while read line
do
  echo $line
done < input.txt

3.   Argumentos de línea de comandos

En un script de bash o función, $1 denota el argumento inicial pasado, $2 denota el segundo argumento pasado, y así sucesivamente.

Este script toma un nombre como argumento de línea de comandos e imprime un saludo personalizado.

#!/bin/bash
echo "Hello, $1!"

Hemos suplido Zaira como nuestro argumento al script.

Salida:

Providing arguments to the bash script

Mostrando la salida:

Aquí discutiremos algunos métodos para recibir salidas de los scripts.

  1. Imprimiendo a la terminal:
echo "Hello, World!"

Esto imprime el texto "Hello, World!" a la terminal.

2.   Escribiendo a un archivo:

echo "This is some text." > output.txt

Esto escribe el teto "This is some text." a un archivo llamado output.txt. Fíjate que el operador > sobreescribe un archivo si éste ya tenía algo de contenido.

3.   Adjuntando a un file:

echo "More text." >> output.txt

Esto adjunta el texto "More text." al final del archivo output.txt.

4.   Redireccionando la salida:

ls > files.txt

Esto lista los archivos en la carpeta actual y escribela salida a un archivo llamado files.txt. Puede redireccionar la salida de cualquier comando a un archivo de esta forma.

Aprenderás sobre redirección de salida en detalle en la sección 8.5.

Declaraciones condicionales (if/else)

Las expresiones que producen un resultado booleano, sea verdadero o falso, son llamados condiciones. Hay varias formas de evaluar condiciones, incluyendo if, if-else, if-elif-else, y condicionales anidadas.

Sintaxis:

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

Sintaxis de las declaraciones condicionales de bash

Podemos usar operadores lógicos tales como AND -a y OR -o para hacer comparaciones que tienen más significado.

if [ $a -gt 60 -a $b -lt 100 ]

Esta declaración verifica si ambas condiciones son true: a es más grande que 60 Y b es menor que 100.

Veamos un ejemplo de un script de Bash que usa declaraciones if, if-else, y if-elif-else para determinar si un número ingresado por el usuario es positivo, negativo, o cero:

#!/bin/bash

# Script to determine if a number is positive, negative, or zero

echo "Please enter a number: "
read num

if [ $num -gt 0 ]; then
  echo "$num is positive"
elif [ $num -lt 0 ]; then
  echo "$num is negative"
else
  echo "$num is zero"
fi

El script primero muestra un mensaje al usuario para que ingrese un número. Luego, usa una declaración if para verificar si el número es más grande que 0. Si lo es, el script muestra que el número es positivo. Si el número no es más grande que 0, el script se mueve a la siguiente declaración, el cual es una declaración if-elif.

Aquí, el script verifica si el número es menor que 0. Si lo es, el script muestra que el número es negativo.

Finalmente, si el número no es más grande que 0 ni menor que 0, el script usa una declaración else para mostrar que el número es cero.

Viéndolo en acción 🚀

Checking if a number is even or odd

Bucles y ramificación en Bash

Bucle while

Los bucles while verifica una condición y un bucle hasta que la condición permanece true. Necesitamos proveer una declaración counter que incrementa el contador para controlar la ejecución del bucle.

En el ejemplo abajo, (( i += 1 )) es la declaración del counter que incrementa el valor de i. El bucle ejecutará exactamente 10 veces.

#!/bin/bash
i=1
while [[ $i -le 10 ]] ; do
   echo "$i"
  (( i += 1 ))
done
Looping from 1 to 10 using

Bucle For

El bucle for, así como el bucle while, te permite ejecutar declaraciones en un número específico de veces. Cada bucle difiere en su sintaxis y uso.

En el ejemplo de abajo, el bucle iterará 5 veces.

#!/bin/bash

for i in {1..5}
do
    echo $i
done
Looping from 1 to 10 using

Declaraciones Case

En Bash, las declaraciones case son usados para comparar un número dado contra una lista de patrones y ejecutar un bloque de código basado en el primer patrón que coincida. La sintaxis para una declaración case en Bash es como sigue:

case expression in
    pattern1)
        # código para ejecutar si la expresión coincide con el patrón1
        ;;
    pattern2)
        # código para ejecutar si la expresión coincide con el patrón2
        ;;
    pattern3)
        # código para ejecutar si la expresión coincide con el patrón3
        ;;
    *)
        # código para ejecutar si ninguno de los patrones de arriba coinciden con la expresión
        ;;
esac

Aquí, "expression" es el valor que queremos comparar, y "pattern1", "pattern2", "pattern3", y así sucesivamente son los patrones con las que queremos comparar.

El doble punto y coma ";;" separa cada bloque de código para ejecutar cada patrón. El asterisco "*" representa el case por defecto, el cual se ejecuta si ninguno de los patrones especificados coinciden con la expresión.

Veamos un ejemplo:

fruit="apple"

case $fruit in
    "apple")
        echo "This is a red fruit."
        ;;
    "banana")
        echo "This is a yellow fruit."
        ;;
    "orange")
        echo "This is an orange fruit."
        ;;
    *)
        echo "Unknown fruit."
        ;;
esac

En este ejemplo, ya que el valor de fruit es apple, el primer patrón ocincide, y el bloque de código que imprime This is a red fruit. se ejecuta. Si el valor de fruit era banana, el segundo patrón coincidiría y el bloque de código que imprime This is a yellow fruit. se ejecutaría, etcétera.

Si el valor de fruit no coincide con ninguno de los patrones especificados, el caso predeterminado se ejecuta, el cual imprime Unknown fruit..

Parte 7: Manejo de Paquetes de Software en Linux

Linux viene con varios programas incorporados. Pero podrías necesitar instalar nuevos programas basado en tus necesidades. También podrías necesitar actualizar las aplicaciones existentes.

7.1. Paquetes y Gestión de Paquetes

¿Qué es un paquete?

Un paquete es una colección de archivos que se empaquetan juntos. Estos archivos son esenciales para que un programa en particular se ejecute. Estos archivos contienen los archivos ejecutables del programa, librerías, y otros recursos.

Además de estos archivos requeridos para el programa para que se ejecute, los paquetes también contienen scripts de instalación, los cuales copian los archivo a donde se les necesita. Un programa podría contener muchos archivos y dependencias. Con los paquetes, es más fácil de manejar todos los archivos y dependencias de una sola vez.

¿Cuál es la diferencia entre fuente y binario?

Los programadores escriben código fuente en un lenguaje de programación. Este código fuente luego se compila en código máquina el cual la computadora puede entender. El código compilado se llama código binario.

Cuando descargas un paquete, puedes obtener el código fuente o el código binario. El código fuente es el código legible para los humanos que puede ser compilado en código binario. El código binario es el código compilado que la computadora puede entender.

Los paquetes fuentes pueden ser usados con cualquier tipo de máquina si el código fuente se compila apropiadamente. El binario, por otro lado, es código compilado que es específico a un tipo particular de máquina o arquitectura.

Puedes encontrar la arquitectura de tu máquina usando el comando uname -m.

uname -m
# output
x86_64

Dependencias de un paquete

Los programas frecuentemente comparten archivos. En vez de incluir estos archivos en cada paquete, un paquete separado puede proveerlos para todos los programas.

Para instalar un programa que necesita estos archivo, también debes instalar el paquete que los contiene. Esto se llama una dependencia de paquete. Especificando las dependencias hacen a los paquetes más pequeños y más sencillo al reducir los duplicados.

Cuando instalas un programa, sus dependencias también deben ser instalados. Las dependencias más requeridas usualmente ya están instaladas, pero unos pares extas podrían ser necesarios. Así que, no te sorprendas si varios paquetes son instalados juntamente con tu paquete deseado. Estos son dependencias necesarias.

Gestores de Paquetes

Linux ofrece un sistema comprensivo de gestión de paquetes para instalar, actualizar, configurar, y quitar software.

Con un gestor de paquetes, puedes obtener acceso a una base organizada de miles de paquetes de software juntamente teniendo la habilidad de resolver dependencias y verificar actualizaciones de software.

Los paquetes pueden ser manejados usando utilidades de línea de comando que pueden ser fácilmente automatizados por los administradores de sistema, o a través de una interfaz gráfica.

Canales/Repositorios de Software

⚠️ La gestión de paquetes es distinto para diferentes distros. Aquí, estamos usando Ubuntu.

Instalando software es un poco distinto en Linux comparado a Windows y Mac.

Linux usa repositorios para almacenar paquetes de software. Un repositorio es una colección de paquetes de software que están disponibles para instalación a través de un gestor de paquetes.

Un gestor de paquetes también almacena un índice de todos los paquetes disponibles de un repo. A veces el índice se reconstruye para asegurarse que está al día y para saber qué paquetes han sido actualizados o agregados al canal desde la última vez que fue verificado.

El proceso genérico de descargar software de un repo se parece algo así:

Rrocess of downloading software from a remote repo

Si hablamos específicamente sobre Ubuntu,

  1. El índice se busca usando apt update. (apt se explica en la próxima sección).
  2. Los archivos/dependencias requeridas se solicitan según el índice usando apt install
  3. Los paquetes y las dependencias se instalan de manera local.
  4. Actualiza las dependencias y los paquetes cuando se requiere usando apt update y apt upgrade

En distros basados en Debian, puedes encontrar la lista de repos (repositorios) en  /etc/apt/sources.list.

7.2. Instalando un paquete a través de la Línea de Comandos

El comando apt es una herramienta de línea de comando poderosa, la cual es parte de Ubuntu y significa "Herramienta de Empaquetamiento Avanzado" ("Advanced Packaging Toll - APT").

apt, junto con los comandos que se empaquetan, provee los medios para instalar nuevos paquetes de software, actualizar paquetes de software existentes, actualizar el índice de lista de paquetes, e inclusive actualizar el sistema de Ubuntu completo.

Para ver los archivos log de la instalación usando apt, puedes ver el archivo /var/log/dpkg.log.

Lo siguiente son los usos del comando apt:

Instalando paquetes

Por ejemplo, para instalar el paquete htop, puedes usar el siguiente comando:

sudo apt install htop

Actualizando el índice de la lista de paquetes

El índice de lista de paquetes es una lista de todos los paquetes disponibles en los repositorios. Para actualizar el índice de la lista de paquetes local, puedes usar el siguiente comando:

sudo apt update

Actualizando los paquetes

Los paquetes instalados en tu sistema puede obtener actualizaciones que contienen correcciones de errores, parches de seguridad, y nuevas características.

Para actualizar los paquetes, puedes usar el siguiente comando:

sudo apt upgrade

Quitando los paquetes

Para quitar un paquete, como htop, puedes usar el siguiente comando:

sudo apt remove htop

7.3. Instalando un paquete a través de un Método Gráfico Avanzado – Synaptic

Si no estás cómodo con la línea de comando, puedes usar una aplicación GUI para instalar paquetes. Puedes alcanzar los mismos resultado como con la línea de comandos, pero con una interfaz gráfica.

Synaptic es una aplicación GUI de gestión de paquetes que ayuda en lista los paquetes instalados, su estado, actualizaciones pendientes, y así sucesivamente. Ofrece filtros personalizables para ayudarte en reducir los resultados de búsqueda.

0f362ed7-c371-4a58-96c2-c359178cdbd9

También puedes hacer clic derecho en un paquete y ver más detalles como las dependencias, el mantenedor, y los archivos instalados.

View a package's detail

7.4. Instalando paquetes descargados de un sitio web

Podrías querer instalar un paquete que has descargado de un sitio web, en vez de un repositorio de software. Estos paquetes se llaman archivos .deb.

Usando dpkg para instalar paquetes:  dpkg es una herramienta de línea de comando que se usa para instalar paquetes. Para instalar un paquete con dpkg, abre la Terminal y escribe lo siguiente:

cd directory
sudo dpkg -i package_name.deb

Nota: Reemplazar "directory" con la carptea donde el paquete se almacena y "package_name" con el nombre del archivo del paquete.

De forma alternativa, puedes hacer clic derecho, selecciona "Open With Other Application", y elige una app GUI de tu gusto.

Installing a software using an app

💡 Consejo: En Ubuntu, puedes ver una lista de paquetes instalados con dpkg --list.

Parte 8: Temas de Linux Avanzados

8.1. Gestión de Usuario

Pueden haber múltiples usuario con niveles variantes de acceso en un sistema. En Linux, el usuario root tiene el nivel más alto de acceso y puede realizar cualquier operación en el sistema. Los usuarios regulares tienen acceso limitado y solamente puede realizar operaciones de las que se les ha dado permiso para hacer.

¿Qué es un usuario?

Una cuenta de usuario provee separación entre distintas personas y programas que pueden ejecutar comandos.

Los humanos identifican a los usuarios por nombre, ya que los nombres son fáciles con los que trabajar. Pero el sistema identifica a los usuarios por un número único llamado el ID de usuario (UID).

Cuando los usuarios humano inician sesión usando el nombre de usuario provisto, tienen que usar una contraseña para autorizarse a ellos mismos.

Las cuentas de usuario forman los fundamentos de la seguridad del sistema. La propiedad de archivo también está asociado con las cuentas de usuario y refuerza el control de acceso a los archivos. Cada proceso tiene una cuenta de usuario asociado que provee una capa de control para los administradores.

Hay tres tipos principales de cuentas de usuario:

  1. Superusuario: El superusuario tiene acceso completo al sistema. El nombre del superusuario es root. Tiene un UID de 0.
  2. Usuario de sistema: El usuario de sistema tiene cuentas de usuario que se usan para ejecutar servicios de sistema. Estas cuentas se usan para ejecutar servicios de sistema y no están destinados para la interacción humana.
  3. Usuario regular: Los usuarios regulares son usuarios humanos que tienen acceso al sistema.

El comando id muestra el ID de usuario y el ID de grupo del usuario actual.

id
uid=1000(john) gid=1000(john) groups=1000(john),4(adm),24(cdrom),27(sudo),30(dip)... output truncated

Para ver las información básica de otro usuario, pasa el nombre de usuario como argumento al comando id.

id username

Para ver la información relacionado al usuario para los procesos, usa el comando ps con el argumento -u.

ps -u
# Salida
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  16968  3920 ?        Ss   18:45   0:00 /sbin/init splash
root         2  0.0  0.0      0     0 ?        S    18:45   0:00 [kthreadd]

Por defecto, los sistemas usan el archivo /etc/passwd para almacenar información de usuario.

Aquí hay una línea del archivo /etc/passwd:

root:x:0:0:root:/root:/bin/bash

El archivo /etc/passwd contiene la siguiente información sobre cada usuario:

  1. Nombre de usuario: root – El nombre de usuario de la cuenta de usuario.
  2. Contraseña: x – La contraseña en formato encriptado para la cuenta de usuario que se almacena en el archivo /etc/shadow por razones de seguridad.
  3. ID de Usuario (UID): 0 – El identificador numérico único para la cuenta de usuario.
  4. ID de Grupo (GID): 0 – El identificador del grupo primario para la cuenta de usuario.
  5. Información de Usuario: root – El nombre real para la cuenta de usuario.
  6. Carpeta Home: /root – The home directory for the user account.
  7. Shell: /bin/bash – El shell predeterminado para la cuenta de usuario. Un usuario de sistema podría usar /sbin/nologin si los inicios de sesión interactivos no están permitidos para ese usuario.

¿Qué es un grupo?

Un grupo es una colección de cuentas de usuario que comparten acceso compartido y recursos. Los grupos tienen nombres de grupo para identificarlos. El sistema identifica a los grupos por un número único llamado el ID del Grupo (GID).

Por defecto, la información sobre los grupos se almacenan en el archivo /etc/group.

Aquí hay una entrada del archivo /etc/group:

adm:x:4:syslog,john

Aquí está el desglose de los campos en la entrada dada:

  1. Nombre de Grupo: adm – El nombre del grupo.
  2. Contraseña: x – La contraseña para el grupo se almacena en el archivo /etc/gshadow por razones de seguridad. La contraseña es opcional y aparece vacío si no se pone una.
  3. ID del Grupo (GID): 4 – El identificador numérico único para el grupo.
  4. Miembros del Grupo: syslog,john – La lista de nombres de usuario que son miembros del grupo. En este caso, el grupo adm tiene dos miembros: syslog y john.

En esta entrada específica, el nombre del grupo es adm, el ID del grupo es 4, y el grupo tiene dos miembros: syslog y john. El campo contraseña es normalmente puesto a x para indicar que la contraseña del grupo se almacena en el archivo /etc/gshadow.

Los grupos están divididos en grupos 'primario' y 'suplementario'.

  • Grupo primario: Cada usuario es asignado un grupo primario por defecto. Este grupo usualmente tiene el mismo nombre como el usuario y se crea cuando la cuenta de usuario se crea. Los archivos y las carpetas creadas por el usuario son normalmente propiedad de este grupo primario.
  • Grupos Suplementarios: Estos son grupos extras a los que un usuario puede pertenecer además de su grupo primario. Los usuarios pueden ser miembros de múltiples grupos suplementarios. Estos grupos permiten a usuario que tenga permisos para los recursos compartidos entre esos grupos. Ayudan a proveer acceso a recursos compartidos sin afectar los permisos del archivo de sistema y manteniendo la seguridad intacta. Mientras que usuario debe pertenecer a un grupo primario, pertenecer a grupos suplementarios is opcional.

Control de acceso: encontrar y entender permisos de archivo

La propiedad de archivo puede ser visto usando el comando ls -l. La primera columna en la salida del comando ls -l muestra los permisos del archivo. Otras columnas muestra al propietario del archivo y el grupo al que el archivo pertenece.

Detailed output of ls -l

Echemos un vistazo más cercano en la columna mode:

Permission classes and file types

Mode define dos cosas:

  • Tipo de archivo: El tipo de archivo define el tipo de archivo. Para archivos regulares que contienen un dato simple está en blanco -. Para otros tipos de archivos especiales el símbolo es distinto. Para una carpeta el cual es un archivo especial, es d. Los archivos especiales son tratados de forma diferente por el SO.
  • Clases de Permiso: El próximo conjunto de caracteres define los permisos para el usuario, el grupo y para otros respectivamente..– User: Este es el propietario de un archivo y el propietario del archivo pertenece a esta clase.– Group: Los miembros del grupo del archivo pertenecen a esta clase– Other: Cualquier usuario que no son parte de las clases del usuario o del grupo pertenecen a esta clase.

💡Consejo: La propiedad de la carpeta se puede ver usando el comando ls -ld.

Cómo leer permisos simbólicos o los permisos de rwx

La representación de rwx es conocido como la representación Simbólca de los permisos. En el conjunto de permisos,

  • r significa read (leer). Se indica en el primer caracter de la tríada.
  • w significa write (escribir). Se indica en el segundo caracter de la tríada.
  • x significa execution (ejecución). Se indica en el tercer caracter de la tríada.

Leer:

Para archivos regulares, los permisos de lectura permiten al archivo que se abra y sea leído solamente. Los usuarios no pueden modificar el archivo.

De forma similar para las carpetas, los permisos de lectura permiten el listado del contenido de la carpeta sin ninguna modificación en la carpeta.

Escribir:

Cuando los archivos tienen permisos, el usuario puede modificar (editar, eliminar) el archivo y guardarlo.

Para las carpetas, los permisos de escritura permiten a un usuario a modificar su contenido (crear, eliminar, y renombrar los archivos que contiene), y modificar el contenido de los archivos de los que el usuario tiene permiso.

Ejemplos de permisos en Linux

Ahora que sabemos cómo leer permisos, veamos algunos ejemplos.

-rwx------: Un archivo que es accesible y ejecutable solamente por su propietario.

-rw-rw-r--: Un archivo que está abierto a modificaciones por su propietario y su grupo pero no por otros.

drwxrwx---: Una carpeta que puede ser modificado por su propietario y su grupo.

Ejecutar:

Para los archivos, los permisos de ejecución permiten al usuario ejecutar un script ejecutable. Para las carpetas, el usuario los puede acceder, y acceder a detalles sobre los archivos en la carpeta.

Cómo cambiar los permisos de archivo y propiedad en Linux usando chmod y chown

Ahora que sabemos las bases de propiedad y permisos, veamos cómo podemos modificar los permisos usando el comando chmod.

Sintaxis de chmod:

chmod permissions filename

Donde,

  • permissions puede ser leído, escrito, ejecutado o una combinación de ellos.
  • filename es el nombre del archivo para los cuales los permisos necesitan para cambiar. Este parámetro también puede ser una lista  de archivos para cambiar permisos en masa.

Podemos cambiar los permisos usando dos modos:

  1. Modo simbólico: este método usa símbolos como u, g, o para representar a los usuarios, a los grupos, y a los otros. Los permisos son representados como r, w, x para lectura, escritura, y ejecución, respectivamente. Puedes modificar los permisos usando +, - y =.
  2. Modo absoluto: este método representa los permisos como números octales de 3 dígitos que van desde 0-7.

Ahora, veámoslos en detalle.

Cómo cambiar los permisos usando el Modo Simbólico

La tabla de abajo resume la representación del usuario:

REPRESENTACION DEL USUARIO DESCRIPCION
u usuario/propietario
g grupo
o otro

Podemos usar operadores matemáticos para agregar, quitar, y asignar permisos. La tabla de abajo muestra el resumen:

OPERADOR DESCRIPCION
+ Agrega un permiso a un archivo o carpeta
Quita el permiso
= Establece el permiso si no estaba presente antes. También sobreescribe los permisos si se pusieron anteriormente.

Ejemplo:

Supongamos que tengo un script y quiero hacerlo ejecutable para el propietario del archivo zaira.

Los permisos de archivos actuales son como sigue:

image-161

Dividamos los permisos así:

Splitting file permissions

Para agregar los derechos de ejecución (x) al propietario (u) usando el modo simbólico, podemos usar el comando de abajo:

chmod u+x mymotd.sh

Salida:

Ahora, podemos ver que los permisos de ejecución han sido agregados al propietario zaira.

Permission updated

Ejemplos adicionales para cambiar los permisos a través del método simbólico:

  • Quitar los permisos de read y write para group y others: chmod go-rw.
  • Quitar los permisos de read para others: chmod o-r.
  • Asignando los permisos de write a group y sobreescribir el permiso existente: chmod g=w.
Cómo cambiar los permisos usando el Modo Absoluto

El modo absoluto usa los números para representar los permisos y operadores matemáticos para modificarlos.

La tabla de abajo muestra cómo podemos asignar permisos relevantes:

PERMISO PROVEER PERMISO
lectura add 4
escritura add 2
ejecución add 1

Los permisos pueden ser revocados usando la resta. La tabla de abajo muestra cómo quitar los permisos relevantes.

PERMISO QUITAR PERMISO
lectura subtract 4
escritura subtract 2
ejecución subtract 1

Ejemplo:

  • Poner read (agregar 4) para user, read (agregar 4) y execute (agregar 1) para el grupo, y solamente execute (agregar 1) para los demás.
chmod 451 file-name

Así es como ejecutamos el cálculo:

Calculation breakdown for adding permissions

Fíjate que esto es lo mismo que r--r-x--x.

  • Quitar derechos de execution desde other y group.

Para quitar la ejecución de other y group, resta 1 de la parte de ejecución de los 2 últimos octatos.

Calculation breakdown for removing permissions
  • Asigna read, write y execute a user, read y execute a group y solamente read a los demás.

Esto debería ser lo mismo que rwxr-xr--.

Calculation breakdown for adding permissions
Cómo cambiar la Propiedad usando el comando chown

Luego, aprenderemos cómo cambiar la propiedad de un archivo. Puedes cambiar la propiedad de un archivo o carpeta usando el comando chown. En algunos casos, cambiar la propiedad requiere permisos sudo.

Sintaxis de chown:

chown user filename
Cómo cambiar la propiedad de usuario con chown

Vamos a transferir la propiedad del usuario zaira al usuario news.

chown news mymotd.sh
view current owner

El comando para cambiar la propiedad: sudo chown news mymotd.sh.

Salida:

Ownership changed
Cómo cambiar la propiedad del usuario y del grupo simultáneamente

También podemos usar chown para cambiar el usuario y el grupo simultáneamente.

chown user:group filename
Cómo cambiar la propiedad de carpeta

Puedes cambiar la propiedad recursivamente para los contenidos en una carpeta. El ejemplo de abajo cambia la propiedad de la carpeta /opt/script para permitir al usuario ser admin.

chown -R admin /opt/script
Cómo cambiar la propiedad de grupo

En caso que solo necesitemos cambiar el propietario del grupo, podemos usar chown al predecir el nombre de grupo con un dos puntos :.

chown :admins /opt/script
Cómo cambiar entre usuarios

Podemos cambiar entre usuarios usando el comando su.

[user01@host ~]$ su user02
Password:
[user02@host ~]$
Cómo ganar acceso de superusuario

El super usuario o el usuario root tiene el nivel de acceso másalto en un sistema Linux. El usuario root puede realizar cualquier operación en el sistema. El usuario root puede acceder a todos los archivos y carpetas, instalar y quitar software, y modificar o sobreescribir configuraciones de sistema.

Un gran poder conlleva una gran responsabilidad. Si el usuario root está comprometido, alguien puede ganar control completo sobre el sistema. Es aconsejable usar las cuentas de usuario root solamente cuando sea necesario.

Si omites el nombre de usuario, el comando su cambia a la cuenta de usuario root por defecto.

[user01@host ~]$ su
Password:
[root@host ~]#

Otra variante del comando su es su -. El comando su cambia a la cuenta de usuario root pero no cambia las variables de entorno. El comando su - cambia a la cuenta de usuario root y cambia las variables de entorno a los del usuario objetivo.

Ejecutar comandos con sudo

Para ejecutar comandos como el usuario root sin cambiar a la cuenta de usuario root, puedes usar el comando sudo. El comando sudo te permite ejecutar comandos con privilegios elevados.

Ejecutar comandos con sudo es una opción más segura que ejecutar los comandos como usuario root. Esto es porque, solamente un conjunto específico de usuarios se les da el permiso de ejecutar comandos con sudo. Esto se define en el archivo /etc/sudoers.

También, sudo muestra en un archivo log todos los comandos con los que ejecuto, proveyendo una pista de auditoría de quién ejecutó qué comando y cuándo.

En Ubuntu, puedes encontrar los archivos log de auditoría aquí:

cat /var/log/auth.log | grep sudo

Para un usuario que no tiene acceso a sudo, se marca en los registros y muestra un mensaje así:

user01 is not in the sudoers file.  This incident will be reported.

Manejar cuentas de usuario locales

Crear usuarios desde la línea de comandos

El comando usado para agregar un nuevo usuario es:

sudo useradd username

Este comando configura un directorio home del usuario y crea un grupo privado designado por el nombre de usuario del usuario. Actualmente, a la cuenta le falta una contraseña válida, previniendo al usuario de iniciar sesión hasta que una contraseña se cree.

Modificar los usuarios existentes

El comando usermod se usa para modificar usuarios existentes. Aquí hay algunas de las opciones comunes usados con el comando usermod:

Aquí algunos de los ejemplos del comando usermod en Linux:

Cambiar un nombre de inicio de sesión del usuario:

 sudo usermod -l newusername oldusername

Cambiar una carpeta de inicio del usuario:

 sudo usermod -d /new/home/directory -m username

Agregar un usuario a un grupo suplementario:

 sudo usermod -aG groupname username

Cambiar un shell del usuario:

 sudo usermod -s /bin/bash username

Bloquear una cuenta de usuario:

 sudo usermod -L username

Desbloquear una cuenta de usuario:

 sudo usermod -U username

Establecer una fecha de vencimiento para una cuenta de usuario:

 sudo usermod -e YYYY-MM-DD username

Cambiar el ID del usuario (UID):

 sudo usermod -u newUID username

Cambiar el grupo primario del usuario:

 sudo usermod -g newgroup username

Quitar un usuario de un grupo suplementario:

sudo gpasswd -d username groupname
Eliminar usuarios

El comando userdel se usa para eliminar una cuenta de usuario y archivos relacionados desde el sistema.

  • sudo userdel username: quita los detalles del usuario desde /etc/passwd pero mantiene la carpeta de inicio del usuario.
  • El comando sudo userdel -r username quita los detalles del usuario desde /etc/passwd y también elimina la carpeta de inicio del usuario.
Cambiar las contraseñas de usuario

El comando passwd se usa para cambiar la contraseña de usuario.

  • sudo passwd username: pone la contraseña inicial o cambia la contraseña existente de nombre de usuario. También se usa para cambiar la contraseña del usuario actual que inició sesión.

8.2 Conectándose a Servidores Remotos a través de SSH

Accediendo a los servidores remotos es una de las tareas esenciales para administradores de sistema. Puedes conectarte a distintos servidores o acceder a bases de datos a través de tu máquina local y ejecutar comandos, todos usando SSH.

¿Qué es el protocol SSH?

SSH significa Shell Seguro (Secure Shell). Es un protocolo de red criptográfico que permite la comunicación segura entre dos sistemas.

El puerto predeterminado para SSH es 22.

Los dos participantes mientras se comunican a través de SSH son:

  • El servidor: la máquina a la que quieres acceder.
  • El cliente: El sistema desde el que estás accediendo al servidor.

La conexión a un servidor sigue estos pasos:

  1. Iniciar una Conexión: El cliente envía una petición de conexión al servidor.
  2. Intercambio de Claves: El servidor envía su clave pública al cliente. Ambos se ponen de acuerdo en el método de encripción a usar.
  3. Generación de Clave de Sesión: El cliente y el servidor usan el intercambio de claves Diffie-Hellman para crear una clave de sesión compartida.
  4. Autenticación de Cliente: El Cliente inicia sesión en el servidor usando una contraseña, clave privada, u otro método.
  5. Comunicación Segura: Después de la autenticación, el cliente y el servidor se comunican de forma segura con encriptación.

¿Cómo conectarse a un servidor remoto usando SSH?

El comando ssh es una utilidad incorporada en Linux y también el predeterminado. Hace que el acceso a los servidores bastante fácil y seguro.

Aquí, estamos hablando sobre cómo el cliente haría una conexión al servidor.

Antes de conectarse a un servidor, necesitas tener la siguiente información:

  • La dirección IP o el nombre de dominio del servidor.
  • El nombre de usuario y contraseña del servidor.
  • El número de puerto del que tienes acceso en el servidor.

La sintaxis básica del comando ssh es:

ssh username@server_ip

Por ejemplo, si tu nombre de usuario es john y la IP del servidor es 192.168.1.10, el comando sería:

ssh john@192.168.1.10

Después de eso, se te mostrará un mensaje para que ingreses la contraseña secreta. Tu pantalla se verá similar a esto:

john@192.168.1.10's password: 
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-70-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Jun  5 10:17:32 UTC 2024

  System load:  0.08               Processes:           122
  Usage of /:   12.3% of 19.56GB   Users logged in:     1
  Memory usage: 53%                IP address for eth0: 192.168.1.10
  Swap usage:   0%

Last login: Fri Jun  5 09:34:56 2024 from 192.168.1.2
john@hostname:~$ # start entering commands

Ahora puedes ejecutar los comandos relevantes en el servidor 192.168.1.10.

⚠️ El puerto predeterminado para ssh es 22 pero también es vulnerable, ya que los hackers probablemente intentarán aquí primero. Tu servidor puede exponer otro puerto y compartir el acceso contigo. Para conectarse a un puerto distinto, usa el argumento -p.

ssh -p port_number username@server_ip

8.3. Análisis Sintáctico y Análisis de Archivos Log Avanzado

Los archivos log, cuando se configuren, son generados por tu sistema por una variedad de razones. Pueden ser usado para rastrear eventos de sistema, monitorear el rendimiento del sistema, y solventar problemas. Son útiles especialmente para los administradores de sistema cuando pueden rastrear errores de aplicación, eventos de red, y actividad de usuario.

Aquí hay un ejemplo de un archivo log:

# ejemplo de un archivo log
2024-04-25 09:00:00 INFO Startup: Application starting
2024-04-25 09:01:00 INFO Config: Configuration loaded successfully
2024-04-25 09:02:00 DEBUG Database: Database connection established
2024-04-25 09:03:00 INFO User: New user registered (UserID: 1001)
2024-04-25 09:04:00 WARN Security: Attempted login with incorrect credentials (UserID: 1001)
2024-04-25 09:05:00 ERROR Network: Network timeout on request (ReqID: 456)
2024-04-25 09:06:00 INFO Email: Notification email sent (UserID: 1001)
2024-04-25 09:07:00 DEBUG API: API call with response time over threshold (Duration: 350ms)
2024-04-25 09:08:00 INFO Session: User session ended (UserID: 1001)
2024-04-25 09:09:00 INFO Shutdown: Application shutdown initiated

Un archivo log usualmente contiene las siguientes columnas:

  • Marca de tiempo: La fecha y el tiempo cuando el evento ocurrió.
  • Nivel de Log: La severidad del evento (INFO, DEBUG, WARN, ERROR).
  • Componente: El componente del sistema que generó el evento (Startup, Config, Database, User, Security, Network, Email, API, Session, Shutdown).
  • Mensaje: Una descripción del evento que ocurrió.
  • Información adicional: Información adicional relacionado al evento.

En sistemas de tiempo real, los archivos log tienden an ser miles de líneas de largo y son generados a cada segundo. Pueden ser verbosos dependiendo de la configuración. Cada columna en un archivo log es una pieza de información que puede ser usado para rastrear problemas. Esto hace que los archivos log sean difíciles de leer y de entender manualmente.

Aquí es donde viene el análisis de archivos log. El análisis estático de archivos log es el proceso de extraer información útil de los archivos log. Involucra descomponer los archivos log en piezas pequeñas más manejables, y extraer la información relevante.

La información filtrada también puede ser útil para crear alertas, reportes y paneles.

En esta sección, explorarás algunas de las técnicas para análisis de archivos log en Linux.

Extracción de texto usando grep

Grep es una utilidad incorporada de bash. Significa "Búsqueda global de expresiones regulares". Grep se usa para hacer coincidir cadenas en archivos.

Aquí hay algunos usos comunes de grep:

Buscar una cadena específica en un archivo:

 grep "search_string" filename

Este comando busca "search_string" en el archivo llamado filename.

Buscar de forma recursiva en las carpetas:

 grep -r "search_string" /path/to/directory

Este comando busca "search_string" en todos los archivos dentro de la carpeta especificada y sus sub-carpetas.

Ignorar mayúsculas y minúsculas mientras se busca:

 grep -i "search_string" filename

Este comando realiza una búsqueda sin importar mayúsculas o minúsculas de "search_string" en el archivo llamado filename.

Mostrar números de línea con líneas coincidentes:

 grep -n "search_string" filename

Este comando muestra los números de línea juntamente con las líneas coincidentes en el archivo llamado filename.

Cuenta el número de líneas coincidentes:

 grep -c "search_string" filename

Este comando cuenta el número de líneas que contiene "search_string" en el archivo llamado filename.

Invertir las coincidencias para mostrar líneas que no coinciden:

 grep -v "search_string" filename

Este comando muestra todas las líneas que no contienen "search_string" en el archivo llamado filename.

Busca una palabra entera:

 grep -w "word" filename

Este comando busca la palabra "word" entera en el archivo llamado filename.

Usar expresiones regulares extendidas:

 grep -E "pattern" filename

Este comando permite el uso de las expresiones regulares extendidas para una coincidencia de patrón más complejo en el archivo llamado filename.

💡 Consejo: Si hay múltiples archivos en una carpeta, puedes usar el comando de abajo para encontrar la lista de archivos que contienen las cadenas deseadas.

# encuentra la lista de archivos que contienen las cadenas deseadas
grep -l "String to Match" /path/to/directory

Extracción de texto usando sed

sed significa "editor de stream". Procesa flujo de datos, lo que significa que lee datos una línea a la vez. sed te permite buscar patrones y realizar acciones en las líneas que coinciden con esos patrones.

Sintaxis básica de sed:

La sintaxis básica de sed es como sigue:

sed [options] 'command' file_name

Aquí, command se usa para realizar operaciones como substitución, eliminación, inserción, y así sucesivamente, en los datos de texto. El nombre de archivo es el nombre del archivo que quieres procesar.

Uso de sed:

1. Substitución:

El argumento s se usa para reemplazar texto. El old-text se reemplaza con new-text:

sed 's/old-text/new-text/' filename

Por ejemplo, para cambiar todas las instancias de "error" a "warning" en el archivo log system.log:

sed 's/error/warning/' system.log

2. Imprimiendo líneas que contienen un patrón específico:

Usando sed para filtrar y mostrar las líneas que coinciden con un patrón específico:

sed -n '/pattern/p' filename

Por ejemplo, para encontrar todas las líneas que contienen "ERROR":

sed -n '/ERROR/p' system.log

3. Eliminar líneas que contienen un patrón específico:

Puedes eliminar líneas desde la salida que coinciden un patrón específico:

sed '/pattern/d' filename

Por ejemplo, para quitar todas las líneas que contienen "DEBUG":

sed '/DEBUG/d' system.log

4. Extrayendo campos específicos desde una línea log:

Puedes usar expresiones regulares para extraer partes de líneas. Supón que cada línea del archivo log comienza con una fecha en el formato "YYYY-MM-DD". Podrías extraer sólo la fecha de cada línea:

sed -n 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/p' system.log

Análisis de Texto con awk

awk tiene la habilidad de separar cada línea fácilmente en los campos. Es adecuado para procesar texto estructurado como archivos log.

Sintaxis Básica de awk

La sintaxis básica de awk es:

awk 'pattern { action }' file_name

Aquí, pattern es una condición que se debe cumplir para que action se ejecute. Si el patrón se omite, la acción se ejecuta en cada línea.

En los próximos ejemplos, usarás este archivo de log como ejemplo:

2024-04-25 09:00:00 INFO Startup: Application starting
2024-04-25 09:01:00 INFO Config: Configuration loaded successfully
2024-04-25 09:02:00 INFO Database: Database connection established
2024-04-25 09:03:00 INFO User: New user registered (UserID: 1001)
2024-04-25 09:04:00 INFO Security: Attempted login with incorrect credentials (UserID: 1001)
2024-04-25 09:05:00 INFO Network: Network timeout on request (ReqID: 456)
2024-04-25 09:06:00 INFO Email: Notification email sent (UserID: 1001)
2024-04-25 09:07:00 INFO API: API call with response time over threshold (Duration: 350ms)
2024-04-25 09:08:00 INFO Session: User session ended (UserID: 1001)
2024-04-25 09:09:00 INFO Shutdown: Application shutdown initiated
  INFO
  • Accediendo a columnas usando awk

Los campos en awk (separados por espacio de forma predeterminada) pueden ser accedidos usando $1, $2, $3, y así sucesivamente.

zaira@zaira-ThinkPad:~$ awk '{ print $1 }' sample.log
# salida
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25
2024-04-25

zaira@zaira-ThinkPad:~$ awk '{ print $2 }' sample.log
# salida
09:00:00
09:01:00
09:02:00
09:03:00
09:04:00
09:05:00
09:06:00
09:07:00
09:08:00
09:09:00
  • Imprimir líneas que contienen un patrón específico (por ejemplo, ERROR)
awk '/ERROR/ { print $0 }' logfile.log

# salida
2024-04-25 09:05:00 ERROR Network: Network timeout on request (ReqID: 456)

Esto imprime todas las líneas que contienen "ERROR".

  • Extraer el primer campo (Fecha y Hora)
awk '{ print $1, $2 }' logfile.log
# salida
2024-04-25 09:00:00
2024-04-25 09:01:00
2024-04-25 09:02:00
2024-04-25 09:03:00
2024-04-25 09:04:00
2024-04-25 09:05:00
2024-04-25 09:06:00
2024-04-25 09:07:00
2024-04-25 09:08:007
2024-04-25 09:09:00

Esto extraerá los dos primeros campos de cada línea, el cual en este caso sería la fecha y hora.

  • Resumir las ocurrencias de cada nivel de log
awk '{ count[$3]++ } END { for (level in count) print level, count[level] }' logfile.log

# output
 1
WARN 1
ERROR 1
DEBUG 2
INFO 6

La salida será un resumen del número de ocurrencias de cada nivel de log.

  • Filtra campos específicos (por ejemplo, donde el 3er campo es INFO)
awk '{ $3="INFO"; print }' sample.log

# salida
2024-04-25 09:00:00 INFO Startup: Application starting
2024-04-25 09:01:00 INFO Config: Configuration loaded successfully
2024-04-25 09:02:00 INFO Database: Database connection established
2024-04-25 09:03:00 INFO User: New user registered (UserID: 1001)
2024-04-25 09:04:00 INFO Security: Attempted login with incorrect credentials (UserID: 1001)
2024-04-25 09:05:00 INFO Network: Network timeout on request (ReqID: 456)
2024-04-25 09:06:00 INFO Email: Notification email sent (UserID: 1001)
2024-04-25 09:07:00 INFO API: API call with response time over threshold (Duration: 350ms)
2024-04-25 09:08:00 INFO Session: User session ended (UserID: 1001)
2024-04-25 09:09:00 INFO Shutdown: Application shutdown initiated
  INFO

Este comando extraerá todas las líneas donde el 3er campo es "INFO".

💡 Consejo: El separador predeterminado en awk es un espacio. Si tu archivo log usa un separador distinto, puedes especificarlo usando la opción -F. Por ejemplo, si tu archivo log usa un dos puntos como separador, puedes usar awk -F: '{ print $1 }' logfile.log para extraer el primer campo.

Análisis de archivos log con cut

El comando cut es una comando sencillo aunque potente usado para extraer secciones de texto de cada línea de la entrada. Siempre y cuando los archivos estén estructurados y cada campo esté delimitado por un caracter específico, tales como un espacio, tabulación, o un delimitador personalizado, cut hace un muy buen trabajo al extraer esos campos específicos.

La sintaxis básica del comando cut es:

cut [opciones] [archivo]

Algunas de las opciones usados comúnmente para el comando cut:

  • -d : Especifica un delimitador usado como el separador de campo.
  • -f : Selecciona los campos para que se muestren.
  • -c : Especifica las posiciones de cada caracter.

Por ejemplo, el comando de abajo extraería el primer campo (separado por un espacio) de cada línea del archivo log:

cut -d ' ' -f 1 logfile.log

Ejemplos de uso de cut para análisis de archivos log

Digamos que tienes un archivo log estructurado como sigue, donde los campos están separados por espacio:

2024-04-25 08:23:01 INFO 192.168.1.10 User logged in successfully.
2024-04-25 08:24:15 WARNING 192.168.1.10 Disk usage exceeds 90%.
2024-04-25 08:25:02 ERROR 10.0.0.5 Connection timed out.
...

cut puede ser usado de las siguientes formas:

  1. Extraer la hora de cada entrada del archivo log:
cut -d ' ' -f 2 system.log

# Output
08:23:01
08:24:15
08:25:02
...

Este comando usa un espacio como un delimitador y selecciona el segundo campo, el cual es el componente hora de cada entrada del archivo log.

2.  Extraer las direcciones IP de los archivos log:

cut -d ' ' -f 4 system.log

# Output
192.168.1.10
192.168.1.10
10.0.0.5

Este comando extraer el cuarto campo, el cual es la dirección IP de cada entrada del log.

3.  Extraer niveles de log (INFO, WARNING, ERROR):

cut -d ' ' -f 3 system.log

# Salida
INFO
WARNING
ERROR

Esto extrae el tercer campo el cual contiene el nivel log.

4.  Combinando cut con otros comandos:

La salida de otros comandos puede ser canalizado al comando cut. Digamos que quieres filtrar los logs antes de cortar. Puedes usar grep para extraer las líneas que contienen "ERROR" y luego usa cut para obtener información específica de esas líneas:

grep "ERROR" system.log | cut -d ' ' -f 1,2 

# Output
2024-04-25 08:25:02

Este comando primero filtra las líneas que incluyen "ERROR", luego extrae la fecha y hora de estas líneas.

5.  Extraer múltiples campos:

Es posible extraer múltiples campos a la vez al especificar un rango o una lista de campos separado por coma:

cut -d ' ' -f 1,2,3 system.log` 

# Salida
2024-04-25 08:23:01 INFO
2024-04-25 08:24:15 WARNING
2024-04-25 08:25:02 ERROR
...

El comando de arriba extrae los tres primeros campos de cada entrada log que son la fecha, hora, y nivel log.

Análisis sintáctico de archivos log con sort y uniq

Ordenar y quitar duplicados son operaciones comunes cuando se trabaja con archivos log. Los comandos sort y uniq son comandos poderosos usados para ordenar y quitar duplicados de las entradas, respectivamente.

Sintaxis básica de sort

El comando sort organiza las líneas de texto de forma alfabética o numérica.

sort [opciones] [archivo]

Algunas opciones claves para el comando sort:

  • -n: Ordena el archivo asumiendo que los contenidos son numéricos.
  • -r: Invierte el orden de sort.
  • -k: Especifica una clave o número de columna con el cual ordena.
  • -u: Ordena y quita líneas duplicadas.

El comando uniq se usa para filtrar o contar y reportar líneas repetidas en un archivo.

La sintaxis de uniq es:

uniq [opciones] [archivo_entrada] [archivo_salida]

Algunas opciones claves para el comando uniq son:

  • -c: Prefija líneas por el número de ocurrencias.
  • -d: Solamente imprime líneas duplicadas.
  • -u: Solamente imprime líneas únicas.

Ejemplos de usar sort y uniq juntos para análisis de archivos log

Asumamos las siguientes de entradas de registro de ejemplo para estas demostraciones:

2024-04-25 INFO User logged in successfully.
2024-04-25 WARNING Disk usage exceeds 90%.
2024-04-26 ERROR Connection timed out.
2024-04-25 INFO User logged in successfully.
2024-04-26 INFO Scheduled maintenance.
2024-04-26 ERROR Connection timed out.
  1. Ordenar entradas log por fecha:
sort system.log

# Salida
2024-04-25 INFO User logged in successfully.
2024-04-25 INFO User logged in successfully.
2024-04-25 WARNING Disk usage exceeds 90%.
2024-04-26 ERROR Connection timed out.
2024-04-26 ERROR Connection timed out.
2024-04-26 INFO Scheduled maintenance.

Esto ordena las entradas log de forma alfabética, el cual ordena efectivamente por fecha si la fecha es el primer campo.

2.  Ordenar y quitar duplicados:

sort system.log | uniq

# Salida
2024-04-25 INFO User logged in successfully.
2024-04-25 WARNING Disk usage exceeds 90%.
2024-04-26 ERROR Connection timed out.
2024-04-26 INFO Scheduled maintenance.

Este comando ordena el archivo log y lo canaliza a uniq, quitando líneas duplicadas.

3.  Contando ocurrencias de cada línea:

sort system.log | uniq -c

# Salida
2 2024-04-25 INFO User logged in successfully.
1 2024-04-25 WARNING Disk usage exceeds 90%.
2 2024-04-26 ERROR Connection timed out.
1 2024-04-26 INFO Scheduled maintenance.

Ordena las entradas de log y luego cuenta cada línea única. Según la salida, la línea '2024-04-25 INFO User logged in successfully.' apareció 2 veces en el archivo.

4.  Identificar entradas de log únicas:

sort system.log | uniq -u

# Salida

2024-04-25 WARNING Disk usage exceeds 90%.
2024-04-26 INFO Scheduled maintenance.

Este comando muestra las líneas que son únicas.

5.  Ordenar por nivel de by log level:

sort -k2 system.log

# Salida
2024-04-26 ERROR Connection timed out.
2024-04-26 ERROR Connection timed out.
2024-04-25 INFO User logged in successfully.
2024-04-25 INFO User logged in successfully.
2024-04-26 INFO Scheduled maintenance.
2024-04-25 WARNING Disk usage exceeds 90%.

Ordena las entradas basado en el segundo campo, el cual es el nivel de registro.

8.4. Gestionando procesos de Linux a través de la Línea de Comandos

Un proceso es una instancia de un programa en ejecución. Un proceso consiste de:

  • Un espacio de dirección de la memora alojada.
  • Estado del Proceso.
  • Propiedades tales como propiedad, atributos de seguridad, y uso de recursos.

Un proceso también tiene un entorno que consiste de:

  • Variables locales y globales
  • El contexto de programación actual
  • Recursos de sistema alojados, tales como puertos de red o descriptores de archivo.

Cuando ejecutes el comando ls -l, el sistema operativo crea un nuevo proceso para ejecutar el comando. El proceso tiene un ID, un estado, y ejecuta hasta que el comando se complete.

Entendiendo la creación de procesos y el ciclo de vida

En Ubuntu, todos los procesos se originan desde el proceso del sistema inicial llamado systemd, el cual el primer proceso comenzó por el kernel durante el arrnque.

El proceso systemd tiene un ID de proceso (PID) de 1 y es responsable por inicializar el sistema, comenzar y gestionar otros procesos, y manejar servicios de sistema. Todos los otros procesos en el sistema son descendientes de systemd.

Un proceso padre duplica su propio espacio de dirección (fork) para crear una nueva estructura de proceso. Cada nuevo proceso se le asigna un ID de proceso único (PID) para rastrear y por propósitos de seguridad. El PID y el ID del proceso del padre (PPID) son parte del nuevo entorno del proceso. Cualquier proceso puede crear un proceso hijo.

Process and its initialization to parent and child

A través de la rutina de fork, un proceso hijo hereda identidades de seguridad, descriptores de archivo previos y actuales, puertos y privilegios de recursos, variables de entorno, y código de programa. Un proceso hijo podría ejecutar su propio código de programa.

Típicamente, un proceso padre se duerme mientras el proceso hijo se ejecuta, estableciendo una petición (wait) para ser notificado cuando el hijo se completa.

Al salir, el proceso hijo ya se cerrado o descartado sus recursos y entorno. El único recurso que permanece, conocido como un zombie, es una entrada en la table del proceso. El padre, señalado como despierto cuando el hijo termina, limpia la tabla del proceso de la entrada del hijo, de esa forma liberando el último recurso del proceso hijo. El proceso padre luego continua ejecutando su propio código de programa.

Entendiendo los estados del proceso

Los procesos en Linux asumen distintos estados durante sus ciclos de vida. El estado de un proceso indica que está haciendo actualmente el proceso y cómo interactúan con el sistema. La transición de procesos entre estados basados en su estado de ejecución y el algoritmo de programación del sistema.

Linux process states and transitions

Los procesos en un sistema Linux puede ser uno de los siguientes estados:

Estado Descripción
(new) El estado inicial cuando un proceso es creado por medio de una llamada del sistema fork.
Runnable (ready) (R) El proceso está listo para ejecutarse y esperando a ser programado en una CPU.
Running (user) (R) El proceso se ejecuta en modo usuario, ejecutando aplicaciones de usuario.
Running (kernel) (R) El proceso se ejecuta en modo kernel, manejando las llamadas de sistema o interrupciones de hardware.
Sleeping (S) El proceso está esperando un evento (por ejemplo, operaciones I/O) para completar y puede ser fácilmente despertado.
Sleeping (uninterruptible) (D) El proceso está en un estado de sueño ininterruptible, esperando una condición específica (usualmente I/O) que se complete, y no puede ser interrumpido por señales.
Sleeping (disk sleep) (K) El proceso está esperando que las operaciones I/O de disco se completen.
Sleeping (idle) (I) El proceso está inactivo, no haciendo ningún trabajo, y esperando que un evento ocurra.
Stopped (T) La ejecución del proceso ha sido detenido, típicamente por una señal, y puede ser reanudado luego.
Zombie (Z) El proceso tiene la ejecución completada pero todavía tiene una entrada en la tabla del proceso, esperando que su antecesor lea su estado de salida.

La transición de los procesos entre estos estados de las siguientes formas:

Transición Descripción
Fork Crea un nuevo proceso desde un proceso antecesor, transicionando de (new) a Runnable (ready) (R).
Schedule El scheduler selecciona un proceso ejecutable, transicionándolo del estado Running (user) o Running (kernel).
Run Las transiciones de proceso desde Runnable (ready) (R) a Running (kernel) (R) cuando se programa para ejecución.
Preempt or Reschedule El proceso puede ser preempted o reprogramado, moviéndolo nuevamente al estado Runnable (ready) (R).
Syscall El proceso hace una llamada de sistema, transicionando de Running (user) (R) a Running (kernel) (R).
Return El proceso completa una llamada de sistema y regresa a Running (user) (R).
Wait El proceso espera un evento, transicionando de Running (kernel) (R) a uno de los estados de sueño (S, D, K, or I).
Event o Signal El proceso se despierta por un evento o señal, cambiándolo de un estado de sueño devuelta a Runnable (ready) (R).
Suspend Process is suspended, transitioning from Running (kernel) or Runnable (ready) to Stopped (T).
Resume El proceso se reanuda, cambiando de Stopped (T) devuelta a Runnable (ready) (R).
Exit El proceso termina, transicionando de Running (user) o Running (kernel) a Zombie (Z).
Reap El proceso antecesor lee el estado de salida del proceso zombie, quitándolo de la tabla de proceso.

Cómo ver los procesos

Puedes usar el comando ps juntamente con una combinación de opciones para ver los procesos en un sistema Linux. El comando ps se usado para mostrar información sobre una selección de procesos activos. Por ejemplo, ps aux muestra todos los procesos que se ejecutan en el sistema.

zaira@zaira:~$ ps aux
# Salida
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0 168140 11352 ?        Ss   May21   0:18 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    May21   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   May21   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   May21   0:00 [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   May21   0:00 [slub_flushwq]
root           6  0.0  0.0      0     0 ?        I<   May21   0:00 [netns]
root          11  0.0  0.0      0     0 ?        I<   May21   0:00 [mm_percpu_wq]
root          12  0.0  0.0      0     0 ?        I    May21   0:00 [rcu_tasks_kthread]
root          13  0.0  0.0      0     0 ?        I    May21   0:00 [rcu_tasks_rude_kthread]
*... output truncated ....*

La salida de arriba muestra un instantáneo de los procesos actuales en ejecución del sistema. Cada fila representa un proceso con las siguientes columnas:

  1. USER: El usuario quien posee el proceso.
  2. PID: El ID del proceso.
  3. %CPU: El uso del CPU del proceso.
  4. %MEM: El uso de memoria del proceso.
  5. VSZ: El tamaño de la memoria virtual del proceso.
  6. RSS: El tamaño del conjunto residente, que es la memoria física no intercambiada que una tarea ha usado.
  7. TTY: La terminal de control del proceso. Un ? indica una terminal de sin control.
  8. STAT: El estado del proceso.
  • R: Running (ejecutando)
  • I o S: Sueño interrumpible (esperando que un evento se complete)
  • D: Sueño ininterrumpible (usualmente IO)
  • T: Detenido (sea por una señal de control de un trabajo o porque está siendo trazado)
  • Z: Zombie (terminado pero no repetido por su padre)
  • Ss: Líder de sesión. Este es un proceso que ha comenzado una sesión, y es un líder de un grupo de procesos y puede controlar señales de la terminal. El primer S indica el estado de dormir, y el segundo s indica que es un líder de sesión.
  1. START: El tiempo de comienzo o fecha del proceso.
  2. TIME: El tiempo de CPU acumulativo.
  3. COMMAND: El comando que comenzó el proceso.

Procesos de segundo y primer plano

En esta sección, aprenderás cómo puedes controlar trabajas al ejecutarlos en segundo o primer plano.

Un trabajo (job) es un proceso que comienza por una shell. Cuando ejecutas un comando en la terminal, se considera un trabajo. Un trabajo puede ejecutarse en primer o segundo plano.

Para demostrar el control, primero crearás 3 procesos y luego los ejecutarás en segundo plano. Después de eso, listarás los procesos y los alternarás entre primer y segundo plano. Verás cómo se los pone a dormir o salir completamente.

  1. Crea tres procesos

Abre una terminal y comienza tres procesos de larga duración. usa el comando sleep, que mantiene el proceso ejecutándose por un número especificado de segundos.

# ejecuta el comando sleep por 300, 400, y 500 segundos
sleep 300 &
sleep 400 &
sleep 500 &

El & al final de cada comando mueve el proceso a segundo plano.

2.   Muestra trabajos en segundo plano

Usa el comando jobs para mostrar la lista de trabajos en segundo plano.

jobs

La salida debería verse así:

jobs
[1]   Running                 sleep 300 &
[2]-  Running                 sleep 400 &
[3]+  Running                 sleep 500 &

3.   Traer un trabajo en segundo plano a primer plano

Para traer un trabajo en segundo plano al primer plano, usa el comando fg seguido del número del trabajo. Por ejemplo, para traer el primer trabajo (sleep 300) al primer plano:

fg %1

Esto traerá el trabajo 1 al primer plano.

4.   Mueve el trabajo en primero plano nuevamente a segundo plano

Mientras el trabajo se ejecuta en el primer plano, puedes suspenderlo y llevarlo nuevamente al segundo plano al presionar Ctrl+Z para suspender el trabajo.

Un trabajo suspendido se verás de esta forma:

zaira@zaira:~$ fg %1
sleep 300

^Z
[1]+  Stopped                 sleep 300

zaira@zaira:~$ jobs
# trabajo suspendido 
[1]+  Stopped                 sleep 300
[2]   Running                 sleep 400 &
[3]-  Running                 sleep 500 &

Ahora usa el comando bg para reanudar el trabajo con ID 1 en el segundo plano.

# Presiona Ctrl+Z para suspender el trabajo de primer plano
# Luego, reanúdalo en segundo plano
bg %1
  1. Muestra los trabajos nuevamente
jobs
[1]   Running                 sleep 300 &
[2]-  Running                 sleep 400 &
[3]+  Running                 sleep 500 &

En este ejercicio, vos:

  • Comenzaste tres proceso en segundo plano usando comandos sleep.
  • Usaste trabajos para mostrar la lista de trabajos en segundo plano.
  • Trajiste un trabajo a primer plano con fg %job_number.
  • Suspendiste el trabajo con Ctrl+Z y lo regresaste al segundo plano con bg %job_number.
  • Usaste los trabajos nuevamente para verificar el estado de los trabajos en segundo plano.

Ahora sanes cómo controlar los trabajos.

Matando procesos

Es posible terminar un proceso que no responde o no querido usando el comando kill. El comando kill envía una señal a un ID de proceso, pidiéndole que termine.

Un número de opciones están disponibles con el comando kill.

# Opciones disponibles con kill

kill -l
 1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) 
...terminated

Aquí hay algunos ejemplos del comando kill en Linux:

Matar un proceso por PID (ID del proceso):

 kill 1234

Este comando envía la señal SIGTERM predeterminada al proceso con un PID de 1234, solicitándole que termine.

Matar un proceso por nombre:

 pkill process_name

Este comando envía la señal SIGTERM predeterminada a todos los procesos con el nombre especificado.

Matar un proceso a la fuerza:

 kill -9 1234

Este comando envía la señal SIGKILL al proceso con el PID 1234, terminándolo a la fuerza.

Envía una señal específica a un proceso:

 kill -s SIGSTOP 1234

Este comando envía la señal SIGSTOP al proceso con el PID 1234, deteniéndolo.

Matar a todos los procesos que pertenecen a un usuario específico:

 pkill -u username

Este comando envía la señal SIGTERM predeterminada a todos los procesos que pertenecen al usuario especificado.

Estos ejemplos demuestran varias formas de usar el comando kill para gestionar procesos en un entorno de Linux.

Aquí esta la información sobre las opciones  y señales del comando kill de una forma tabular: Esta tabla resumen las opciones y señales más comunes del comando kill usados para gestionar los procesos.

Comando / Opción Señal Descripción
kill <pid> SIGTERM Solicita al proceso que termina correctamente (señal predeterminada).
kill -9 <pid> SIGKILL Forza al proceso que termine inmediatamente sin limpiar.
kill -SIGKILL <pid> SIGKILL Forza al proceso que termine inmediatamente sin limpiar.
kill -15 <pid> SIGTERM Envía explícitamente la señal SIGTERM para solicitar la terminación correcta.
kill -SIGTERM <pid> SIGTERM Envía explícitamente la señal SIGTERM para solicitar la terminación correcta.
kill -1 <pid> SIGHUP Tradicionalmente significa "colgarse"; puede ser usado para recargar archivos de configuración.
kill -SIGHUP <pid> SIGHUP Tradicionalmente significa "colgarse"; puede ser usado para recargar archivos de configuración.
kill -2 <pid> SIGINT Solicita al proceso que termine (lo mismo que presionar Ctrl+C en la terminal).
kill -SIGINT <pid> SIGINT Solicita al proceso que termine (lo mismo que presione Ctrl+C en la terminal).
kill -3 <pid> SIGQUIT Hace que el proceso termine y produzca un core dump para depuración.
kill -SIGQUIT <pid> SIGQUIT Hace que el proceso termine y produzca un core dump para depuración.
kill -19 <pid> SIGSTOP Pausa el proceso.
kill -SIGSTOP <pid> SIGSTOP Pausa el proceso.
kill -18 <pid> SIGCONT Reanuda un proceso pausado.
kill -SIGCONT <pid> SIGCONT Reanuda un proceso pausado.
killall <nombre> Varios Envía una señal a todos los procesos con el nombre provisto.
killall -9 <nombre> SIGKILL Forza que mate a todos los procesos con el nombre provisto.
pkill <patron> Varios Envía una señal a los procesos basado en una coincidencia de patrón.
pkill -9 <patron> SIGKILL Forza que mate a todos los procesos que coincida con el patrón.
xkill SIGKILL Utilidad gráfica que permite hacer clic en una ventana para que mate al proceso correspondiente.

8.5. Flujos de Entrada y Salida Estándar en Linux

Leer una entrada y escribir una entrada es una parte esencial de entender la línea de comandos y la programación de scripts. En Linux, cada proceso tiene tres flujos predeterminados:

Entrada Estándar (stdin): Este flujo se usa para entradas, típicamente desde el teclado. Cuando un programa lee desde el stdin, recibe datos ingresados por el usuario o redireccionado desde un archivo. Un descriptor de archivo es un identificador único que el sistema operativo asigna a un archivo abierto para mantener un rastro de archivos abiertos.

El descriptor de archivo para stdin es 0.

Salida Estándar (stdout): Este es el flujo de salida predeterminado donde un proceso escribe su salida. Por defecto, la salida estándar es la terminal. La salida también puede ser redireccionado a un archivo u otro programa. El descriptor de archivo para stdout es 1.

Error Estándar (stderr): Este es el flujo de error estándar donde un proceso escribe sus mensajes de error. Por defecto, el error estándar es la terminal, permitiendo que los mensajes de error sea visto inclusive si stdout es redireccionado. El descriptor de archivo para stderr es 2.

Redirección y Tuberías

Redirección: Puedes redireccionar el error y los flujos de salida a los archivos u otros comandos. Por ejemplo:

# Redireccionando stdout a un archivo
ls > output.txt

# Redireccionando stderr a un archivo
ls non_existent_directory 2> error.txt

# Redireccionando stdout y stderr a un archivo
ls non_existent_directory > all_output.txt 2>&1

En el último comando,

  • ls non_existent_directory: lista los contenidos de una carpeta llamada non_existent_directory. Ya que esta carpeta no existe, ls generará un mensaje de error.
  • > all_output.txt: El operador > redirecciona la salida estándar (stdout) del comando ls al archivo all_output.txt. Si el archivo no existe, será creado. Si existe, su contenido será sobrescrito.
  • 2>&1:: Aquí, 2 representa el descriptor del archivo para el error estándar (stderr). &1 representa el descriptor del archivo para la salida estándar (stdout). El caracter & se usa para especificar que 1 no es el nombre del archivo sino un descriptor del archivo.

Así que, 2>&1 significa "redirecciona stderr (2) a donde sea que stdout (1) esté yendo actualmente", el cual en este caso es el archivo all_output.txt. Por lo tanto, la salida (si hay uno) y el mensaje de error de ls será escrito a all_output.txt.

Tuberías:

Puedes usar tuberías (|) para pasar la salida de un comando como la entrada a otro:

ls | grep image
# Salida
image-10.png
image-11.png
image-12.png
image-13.png
... Output truncated ...

8.6 Automatización en Linux – Automatizar Tareas con Tareas de Cron

Cron es una utilidad poderosa para programar trabajos que está disponible en sistemas operativos de Unix. Al configurar un cron, puedes configurar trabajos automatizados para ejecutar diariamente, mensualmente, u otro tiempo específico. Las capacidades de automatización provisto por cron juega un rol crucial en la administración de sistema de Linux.

El daemon crond (un tipo de programa de computadora que se ejecuta en segundo plano) permite la funcionalidad de cron. El cron lee el crontab (tablas de cron) para ejecutar scripts predefinidos.

Al usar una sintaxis específica, puedes configurar un trabajo cron para programar scripts u otros comandos para ejecutarlos automáticamente.

¿Qué son los trabajos cron en Linux?

Cualquier tarea que programes a través de crons se llama un trabajo de cron.

Ahora, veamos cómo los trabajos de cron funcionan.

Cómo controlar el acceso a los crons

Para usar los trabajos de cron, un administrador necesita permitir a los trabajos de cron que sean agregados para los usuarios en el archivo /etc/cron.allow.

Si obtienes un mensaje como este, significa que no tienes permiso para usar cron.

Cron job addition denied for user John.

Para permitir a John que use crons, incluye su nombre en /etc/cron.allow. Crea el archivo si no existe. Esto permitirá a John que cree y edite trabajos de cron.

Allowing John in file cron.allow

Los usuarios también se les puede denegar el acceso a trabajos de cron al ingresar sus nombres de usuario en el archivo /etc/cron.d/cron.deny.

Cómo agrega trabajos de cron en Linux

Primero, para usar los trabajos de cron, necesitarás verificar el estado del servicio de cron. Si cron no está instalado, puedes descargarlo fácilmente a través del gestor de paquetes. Solo usa esto para verificar:

# Check cron service on Linux system
sudo systemctl status cron.service

Sintaxis de trabajos de Cron

Los crontabs usan los siguientes argumentos para agregar y listar trabajos de cron:

  • crontab -e: edita las entradas de crontab para agregar, eliminar, o editar trabajos de cron.
  • crontab -l: listar todos los trabajos de cron para el usuario actual.
  • crontab -u nombre-usuario -l: lista los crons de otro usuario.
  • crontab -u nombre-usuario -e: edita los crons de otro usuario.

Cuando listas los crons y existen, verás algo como esto:

# Cron job example
* * * * * sh /path/to/script.sh

En el ejemplo de arriba,

  • * representa minuto(s) hora(s) día(s) mes(es) semana(s), respectivamente. Ve los detalles de estos valores abajo:
VALOR DESCRIPCIÓN
Minutos 0-59 El comando será ejecutado en el minuto específico.
Horas 0-23 El comando será ejecutado en la hora específica.
Días 1-31 Los comandos serán ejecutados en estos días de los meses.
Meses 1-12 El mes en el que las tareas necesitan ser ejecutados.
Días de la semana 0-6 Días de la semana donde los comandos se ejecutarán. Aquí, 0 es Domingo.
  • sh representa que el script es un script de bash y debería ser ejecutado desde /bin/bash.
  • /path/to/script.sh especifica la ruta al script.

Abajo hay un resumen de la sintaxis de los trabajos de cron:

*   *   *   *   *  sh /path/to/script/script.sh
|   |   |   |   |              |
|   |   |   |   |      Comando o Script a ejecutarse        
|   |   |   |   |
|   |   |   |   |
|   |   |   |   |
|   |   |   | Día de la Semana(0-6)
|   |   |   |
|   |   | Mes del Año(1-12)
|   |   |
|   | Día del Mes(1-31)  
|   |
| Hora(0-23)  
|
Min(0-59)

Ejemplos de Trabajos de Cron

Abajo hay algunos ejemplos de programación de trabajos de cron.

PROGRAMACIÓN VALOR DE LA PROGRAMACIÓN
5 0 * 8 * A las 00:05 en Agosto.
5 4 * * 6 A las 04:05 el Sábado.
0 22 * * 1-5 A las 22:00 cada día de la semana desde Lunes hasta Viernes.

No hay problema si no logras comprender todo esto de una vez. Puedes practicar y generar cronogramas con el sitio web crontab guru.

Cómo configurar un trabajo cron

En esta sección, veremos un ejemplo de cómo programar un script sencillo con un trabajo cron.

  1. Crea un script llamado date-script.sh el cual imprime la fecha y hora del sistema y lo adjunta a un archivo. El script se muestra abajo:
#!/bin/bash

echo `date` >> date-out.txt

2.   Haz que el script sea ejecutable al darle derechos de ejecución.

chmod 775 date-script.sh

3.   Agrega el script en el crontab usando crontab -e.

Aquí, lo hemos programado para que se ejecute por minuto.

*/1 * * * * /bin/sh /root/date-script.sh

4.   Verifica la salida del archivo date-out.txt. Según el script, la fecha del sistema debería ser impreso a este archivo cada minuto.

cat date-out.txt
# Salida
Wed 26 Jun 16:59:33 PKT 2024
Wed 26 Jun 17:00:01 PKT 2024
Wed 26 Jun 17:01:01 PKT 2024
Wed 26 Jun 17:02:01 PKT 2024
Wed 26 Jun 17:03:01 PKT 2024
Wed 26 Jun 17:04:01 PKT 2024
Wed 26 Jun 17:05:01 PKT 2024
Wed 26 Jun 17:06:01 PKT 2024
Wed 26 Jun 17:07:01 PKT 2024

Cómo solucionar problemas de crons

Los crons son realmente útiles, pero no podrían funcionar siempre como se espera. Afortunadamente, hay algunos métodos efectivos que puedes usar para solucionar problemas.

1. Verifica la programación.

Primero, puedes intentar verificar la programación que fue hecho para el cron. Puedes hacer eso con la sintaxis que viste en las secciones de arriba.

2. Verificar archivos log de cron.

Primero, necesita verificar si el con se ha ejecutado en el tiempo previsto o no. En Ubuntu, puedes verificarlo desde los logs de cron localizado en /var/log/syslog.

Si hay una entrada en estos logs en el tiempo correcto, significa que el cron se ha ejecutado según la planificación que estableciste.

Abajo están los logs de nuestro ejemplo de un trabajo de cron. Fíjate que la primer columna el cual muestra la marca de tiempo. La ruta del script también se menciona al final de la línea. Línea #1, 3, y 5 muestra que el script se ejecutó como se esperaba.

1 Jun 26 17:02:01 zaira-ThinkPad CRON[27834]: (zaira) CMD (/bin/sh /home/zaira/date-script.sh)
2 Jun 26 17:02:02 zaira-ThinkPad systemd[2094]: Started Tracker metadata extractor.
3 Jun 26 17:03:01 zaira-ThinkPad CRON[28255]: (zaira) CMD (/bin/sh /home/zaira/date-script.sh)
4 Jun 26 17:03:02 zaira-ThinkPad systemd[2094]: Started Tracker metadata extractor.
5 Jun 26 17:04:01 zaira-ThinkPad CRON[28538]: (zaira) CMD (/bin/sh /home/zaira/date-script.sh)

3. Redireccionar la salida del cron a un archivo.

Puedes redireccionar una salida del cron a un archivo y verificar si el archivo tiene algún error posible.

# Redirige la salida de cron a un archivo
* * * * * sh /path/to/script.sh &> log_file.log

8.7. Conceptos Básicos de Redes de Linux

Linux ofrece un número de comandos para ver la información relacionado a la red. En esta sección discutiremos brevemente algunos de los comandos.

Ver interfaces de red con ifconfig

El comando ifconfig provee información sobre las interfaces de red. Aquí hay un ejemplo de salida:

ifconfig

# Salida
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fe4e:66a1  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:4e:66:a1  txqueuelen 1000  (Ethernet)
        RX packets 1024  bytes 654321 (654.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 512  bytes 123456 (123.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 256  bytes 20480 (20.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 256  bytes 20480 (20.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

La salida del comando ifconfig muestra las interfaces de red configurados en el sistema, juntamente con detalles tales como direcciones IP, direcciones MAC, estadísticas de paquetes, y más.

Estas interfaces pueden ser dispositivos físicos o virtuales.

Para extraer las direcciones IPv4 y IPv6, puedes usar ip -4 addr y ip -6 addr, respectivamente.

Ver la actividad de red con netstat

El comando netstat muestra las estadísticas y la actividad de la red al dar la siguiente información:

Aquí hay algunos ejemplos al usar el comando netstat en la línea de comandos:

Muestra todos los sockets de escucha y no escucha:

 netstat -a

Muestra solamente los puertos en escucha:

 netstat -l

Muestra las estadísticas de red:

 netstat -s

Muestra la tabla de enrutamiento:

 netstat -r

Muestra las conexiones TCP:

 netstat -t

Muestra las conexiones UDP:

 netstat -u

Muestra las interfaces de red:

 netstat -i

Muestra el PID y los nombres de programa para las conexiones:

 netstat -p

Muestra las estadísticas para un protocolo específico (por ejemplo, TCP):

 netstat -st

Mostrar información extendida:

netstat -e

Verifica la conectividad de red entre dos dispositivos usando ping

ping se usa para probar la conectividad de red entre dos dispositivos. Envía paquetes ICMP al dispositivo objetivo y espera una respuesta.

ping google.com

ping prueba si obtienes una respuesta sin recibir un tiempo de espera.

ping google.com
PING google.com (142.250.181.46) 56(84) bytes of data.
64 bytes from fjr04s06-in-f14.1e100.net (142.250.181.46): icmp_seq=1 ttl=60 time=78.3 ms
64 bytes from fjr04s06-in-f14.1e100.net (142.250.181.46): icmp_seq=2 ttl=60 time=141 ms
64 bytes from fjr04s06-in-f14.1e100.net (142.250.181.46): icmp_seq=3 ttl=60 time=205 ms
64 bytes from fjr04s06-in-f14.1e100.net (142.250.181.46): icmp_seq=4 ttl=60 time=100 ms
^C
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 78.308/131.053/204.783/48.152 ms

Puedes detener la respuesta con Ctrl + C.

Probando recursos con el comando curl

El comando curl significa "URL del cliente". Se usa para transferir datos a un o de un servidor. También puede ser usado para probar recursos de una API lo que ayuda en solucionar errores de sistema y de aplicaciones.

Como un ejemplo, puedes usar http://www.official-joke-api.appspot.com/ para experimentar con el comando curl.

  • El comando curl sin ninguna opción usa el método GET por defecto.
curl http://www.official-joke-api.appspot.com/random_joke
{"type":"general",
"setup":"What did the fish say when it hit the wall?","punchline":"Dam.","id":1}
  • curl -o guarda la salida al archivo mencionado.
curl -o random_joke.json http://www.official-joke-api.appspot.com/random_joke
# saves the output to random_joke.json
  • curl -I busca solamente las cabeceras.
curl -I http://www.official-joke-api.appspot.com/random_joke
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Vary: Accept-Encoding
X-Powered-By: Express
Access-Control-Allow-Origin: *
ETag: W/"71-NaOSpKuq8ChoxdHD24M0lrA+JXA"
X-Cloud-Trace-Context: 2653a86b36b8b131df37716f8b2dd44f
Content-Length: 113
Date: Thu, 06 Jun 2024 10:11:50 GMT
Server: Google Frontend

8.8. Solucionando problemas de Linux: Herramientas y Técnicas

Reporte de actividad del Sistema con sar

El comando sar en Linux es una herramienta poderosa para recolectar, reportar, y guardar información de estadísticas del sistema. Es parte del paquete sysstat y es ampliamente usado para monitorear el rendimiento del sistema con el tiempo.

Para usar sar primero necesitas instalar sysstat usando sudo apt install sysstat.

Una vez instalado, comienza el servicio con sudo systemctl start sysstat.

Verifica el estado con sudo systemctl status sysstat.

Una vez que el estado esté activo, el sistema comenzará a recolectar varias estadísticas que puedes usar para acceder y analizar datos históricos. Veremos eso en detalle pronto.

La sintaxis del comando sar es como sigue:

sar [opciones] [intervalo] [cuenta]

Por ejemplo, sar -u 1 3 mostrará el uso de estadísticas del CPU por segundo tres veces.

sar -u 1 3
# Salida
Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

19:09:26        CPU     %user     %nice   %system   %iowait    %steal     %idle
19:09:27        all      3.78      0.00      2.18      0.08      0.00     93.96
19:09:28        all      4.02      0.00      2.01      0.08      0.00     93.89
19:09:29        all      6.89      0.00      2.10      0.00      0.00     91.01
Average:        all      4.89      0.00      2.10      0.06      0.00     92.95

Aquí hay algunos de los casos de uso comunes y ejemplos de cómo usar el comando sar.

sar puede ser usado para una variedad de propósitos:

1. Uso de Memoria

Para verificar el uso de memoria (libre y usado), usa:

sar -r 1 3

Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

19:10:46    kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
19:10:47      4600104   8934352   5502124     36.32    375844   4158352  15532012     65.99   6830564   2481260       264
19:10:48      4644668   8978940   5450252     35.98    375852   4165648  15549184     66.06   6776388   2481284        36
19:10:49      4646548   8980860   5448328     35.97    375860   4165648  15549224     66.06   6774368   2481292       116
Average:      4630440   8964717   5466901     36.09    375852   4163216  15543473     66.04   6793773   2481279       139

Este comando muestra las estadísticas de memoria cada segundo tres veces.

2. Utilización del espacio de intercambio (Swap)

Para ver las estadísticas del uso del espacio de swap, usa:

sar -S 1 3

sar -S 1 3
Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

19:11:20    kbswpfree kbswpused  %swpused  kbswpcad   %swpcad
19:11:21      8388604         0      0.00         0      0.00
19:11:22      8388604         0      0.00         0      0.00
19:11:23      8388604         0      0.00         0      0.00
Average:      8388604         0      0.00         0      0.00

Este comando ayuda en monitorear el uso de swap, lo cual es crucial para los sistemas que quedan sin espacio de memoria física.

3. Carga de dispositivos I/O

Para reportar actividad de dispositivos de bloque y particiones de dispositivos de bloque:

sar -d 1 3

Este comando provee estadísticas detallados sobre las transferencias de datos de los dispositivos de bloque, y es útil para diagnosticar cuellos de botella de I/O.

5. Estadísticas de Red

Para ver las estadísticas de red, como el número de paquetes recibidos (transmitidos) por la interfaz de red:

sar -n DEV 1 3
# -n DEV le dice a sar que reporte interfaces de dispositivos de red
sar -n DEV 1 3
Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

19:12:47        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
19:12:48           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
19:12:48       enp2s0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
19:12:48       wlp3s0     10.00      3.00      1.83      0.37      0.00      0.00      0.00      0.00
19:12:48    br-5129d04f972f      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
.
.
.

Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
Average:           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:       enp2s0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
...output truncated...

Esto muestra las estadísticas de red cada segundo por tres segundos, lo que ayuda en monitorear el tráfico de red.

6. Datos históricos

Recuerda que instalamos el paquete sysstat previamente  y ejecutamos el servicio. Sigue los pasos de abajo para permitir y acceder a los datos históricos.

Permitir recolección de datos: Edita el archivo de configuración sysstat para permitir la recolección de datos.

 sudo nano /etc/default/sysstat

Cambia ENABLED="false" a ENABLED="true".

 vim /etc/default/sysstat
 #
 # Configuraciones predeterminadas para los archivos /etc/init.d/sysstat, /etc/cron.d/sysstat
 # y /etc/cron.daily/sysstat
 #

 # ¿Debería sadc recolectar información de la actividad del sistema? Valores válidos
 # son "true" y "false". Por favor no pongas otros valores, serán
 # anulados por debconf!
 ENABLED="true"

Configura el intervalo de recolección de datos: Edita la configuración del trabajo de cron para poner el intervalo de recolección de datos.

 sudo nano /etc/cron.d/sysstat

Por defecto, recolecta datos cada 10 minutos. Puedes ajustar el intervalo al modificar la planificación del trabajo de cron. Los archivos relevantes irán a la carpeta /var/log/sysstat.

Ver los datos históricos: Usa el comando sar para ver los datos históricos. Por ejemplo, para ver el uso del CPU para el día actual:

 sar -u

Para ver los datos desde una fecha específica:

 sar -u -f /var/log/sysstat/sa<DD>

Reemplaza <DD> con el día del mes con el cual quieres ver los datos.

En el comando de abajo, /var/log/sysstat/sa04 provee estadísticas para el cuarto día del mes actual.

sar -u -f /var/log/sysstat/sa04
Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

15:20:49     LINUX RESTART    (12 CPU)

16:13:30     LINUX RESTART    (12 CPU)

18:16:00        CPU     %user     %nice   %system   %iowait    %steal     %idle
18:16:01        all      0.25      0.00      0.67      0.08      0.00     99.00
Average:        all      0.25      0.00      0.67      0.08      0.00     99.00
7. Interrupciones de la CPU en tiempo real

Para observar interrupciones en tiempo real por segundo servido por la CPU, usa este comando:

sar -I SUM 1 3

# Salida
Linux 6.5.0-28-generic (zaira-ThinkPad)     04/06/24     _x86_64_    (12 CPU)

19:14:22         INTR    intr/s
19:14:23          sum   5784.00
19:14:24          sum   5694.00
19:14:25          sum   5795.00
Average:          sum   5757.67

Este comando ayuda a monitorear con cuanta frecuencia la CPU maneja las interrupciones, lo cual puede ser crucial para ajuste de rendimiento en tiempo real.

Estos ejemplos ilustran cómo puedes usar sar para monitorear varios aspectos del rendimiento de sistema. El uso regular de sar puede ayudar a identificar los cuellos de botella del sistema y asegurar que las aplicaciones se mantenga ejecutando de forma eficiente.

8.9. Estrategia General para Solucionar Problemas para los Servidores

¿Por qué necesitamos entender sobre monitoreo?

El monitoreo de sistema es un aspecto importante de la administración de sistema. Las aplicaciones críticas demandan un alto nivel de proactividad para prevenir fallas y reducir el impacto de cortes.

Linux ofrece herramientas muy potentes para medir la salud del sistema. En esta sección, aprenderás sobre los varios métodos disponibles para verificar la salud del sistema e identificar los cuellos de botella.

Encontrar el promedio de carga y tiempo de actividad del sistema

Los reinicios de sistema podría ocurrir lo cual puede a veces arruinar algunas configuraciones. Para verificar cuánto tiempo la máquina estuvo activa, usa el comando: uptime. Además del tiempo de actividad, el comando también muestra el promedio de carga.

[user@host ~]$ uptime 19:15:00 up 1:04, 0 users, load average: 2.92, 4.48, 5.20

El promedio de carga es la carga del sistema durante los minutos 1, 5 y 15. Un vistazo rápido indica si la carga de sistema está en incremento o disminuyendo con el tiempo.

Nota: la cola de CPU ideal es 0. Esto es posible solamente cuando no hay colas de espera para la CPU.

Cada carga de CPU puede ser calculado al dividir el promedio de carga con el número total de CPUs disponibles.

Para encontrar el número de CPUs, usa el comando lscpu.

lscpu
# Salida
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         48 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  12
  On-line CPU(s) list:   0-11
.
.
.
Salida omitido

Si el promedio de carga parece incrementar y no se va para abajo, los CPUs están sobrecargados. Hay algún proceso que está estancado o hay fuga de memoria.

Calculando memoria libre

A veces, el alto uso de memoria podría causar problemas. Para verificar la memoria disponible y la memoria en uso, usa el comando free.

free -mh
# Salida
               total        used        free      shared  buff/cache   available
Mem:            14Gi       3.5Gi       7.7Gi       109Mi       3.2Gi        10Gi
Swap:          8.0Gi          0B       8.0Gi

Calculando el espacio de disco

Para asegurarse que el sistema está saludable, no te olvides sobre el espacio de disco. Para listar todos los puntos de montaje disponible y su porcentaje usado respectivamente, usa el comando de abajo. Idealmente, los espacios de disco utilizados no deberían exceder un 80%.

El comando df provee espacios de disco detallados.

df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           1.5G  2.4M  1.5G   1% /run
/dev/nvme0n1p2  103G   34G   65G  35% /
tmpfs           7.3G   42M  7.2G   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
efivarfs        246K   93K  149K  39% /sys/firmware/efi/efivars
/dev/nvme0n1p3  130G   47G   77G  39% /home
/dev/nvme0n1p1  511M  6.1M  505M   2% /boot/efi
tmpfs           1.5G  140K  1.5G   1% /run/user/1000

Determinando los estados de proceso

Los estados de proceso pueden ser monitoreados para ver cualquier proceso estancado con un alto uso de memoria o de CPU.

Vimos anteriormente que el comando ps nos da información útil sobre un proceso. Pega un vistazo a las columnas CPU y MEM.

[user@host ~]$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
 runner         1  0.1  0.0 1535464 15576 ?       S  19:18   0:00 /inject/init
 runner        14  0.0  0.0  21484  3836 pts/0    S   19:21   0:00 bash --norc
 runner        22  0.0  0.0  37380  3176 pts/0    R+   19:23   0:00 ps aux

Monitoreo del sistema en tiempo real

El monitoreo en tiempo real provee una ventana en el estado del sistema en tiempo real.

Una utilidad que puedes usar para hacer esto es el comando top.

El comando de arriba muestra una vista dinámica de los procesos del sistema, mostrando un resumen de la cabecera seguido de un proceso o una lista de hilos. A diferencia de su contraparte estática ps, top refresca continuamente las estadísticas del sistema.

Con top, puedes ver detalles bien organizados en una ventana compacta. Hay un número de argumentos, atajos y métodos resaltados que vienen junto con top.

También puedes matar procesos usando top. Para eso, presiona k y luego ingresa el id del proceso.

Interpretando archivos log

Los archivos log de sistema y de aplicaciones conllevan muchísima información sobre el cual el sistema está pasando. Contienen información útil y códigos de error que apuntan a errores. Si buscas códigos de errores en los archivos log, la identificación de problemas y el tiempo de rectificación pueden ser reducidos enormemente.

Análisis de puertos de Red

El aspecto de red no debería ser ignorado ya que los fallos de red son comunes y podrían impactar en el sistema y en el flujo de tráfico. Problemas de red comunes incluyen agotamiento de puerto, asfixia de puerto, recursos sin liberarse, etcétera.

Para identificar tales problemas, necesitamos entender los estados de puerto.

Algunos de los estados de puertos son explicados de forma breve aquí:

Estado Descripción
LISTEN Representa a los puertos que están esperando una solicitud de conexión de cualquier TCP y puerto remoto.
ESTABLISHED Representa a las conexiones que están abiertas y los datos recibidos pueden ser entregados a su destino.
TIME WAIT Representa el tiempo de espera para asegurar el reconocimiento de su solicitud de terminación de la conexión.
FIN WAIT2 Representa la espera de una solicitud de terminación de conexión del TCP remoto.

Exploremos cómo podemos analizar la información relacionado a los puertos en Linux.

Rangos de Puerto: Los rangos de puerto son definidos en el sistema, y los rangos pueden ser aumentados/disminuidos respectivamente. En el fragmento de abajo, el rango es desde 15000 a 65000, lo cual hace un total de 50000 (65000 - 15000) de puertos disponibles. Si los puertos utilizados están alcanzando o excediendo este límite, entonces hay un problema.

[user@host ~]$ /sbin/sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 15000    65000

El error reportado en los archivos log en tales casos puede ser Failed to bind to port o Too many connections.

Identificando pérdidas de paquetes

En el monitoreo de sistema, necesitamos asegurarnos que la comunicación entrante y saliente está intacto.

Un comando útil es ping. ping llega al sistema destinatario y trae de vuelta la respuesta. Fíjate que las últimas pocas líneas de estadísticas que muestran el porcentaje y tiempo de la pérdida de los paquetes.

# ping IP destinatario
[user@host ~]$ ping 10.13.6.113
 PING 10.13.6.141 (10.13.6.141) 56(84) bytes of data.
 64 bytes from 10.13.6.113: icmp_seq=1 ttl=128 time=0.652 ms
 64 bytes from 10.13.6.113: icmp_seq=2 ttl=128 time=0.593 ms
 64 bytes from 10.13.6.113: icmp_seq=3 ttl=128 time=0.478 ms
 64 bytes from 10.13.6.113: icmp_seq=4 ttl=128 time=0.384 ms
 64 bytes from 10.13.6.113: icmp_seq=5 ttl=128 time=0.432 ms
 64 bytes from 10.13.6.113: icmp_seq=6 ttl=128 time=0.747 ms
 64 bytes from 10.13.6.113: icmp_seq=7 ttl=128 time=0.379 ms
 ^C
 --- 10.13.6.113 ping statistics ---
 7 packets transmitted, 7 received,0% packet loss, time 6001ms
 rtt min/avg/max/mdev = 0.379/0.523/0.747/0.134 ms

Los paquetes también pueden ser capturados en tiempo de ejecución usando tcpdump. Veremos esto más adelante.

Reuniendo estadísticas para problemas críticos

Siempre es una buena práctica reunir ciertas estadísticas que sería útil para identificar la causa raíz luego. Usualmente, después del reinicio del sistema o del reinicio de los servicios, perdemos los instantáneos y archivos log previos del sistema.

Abajo hay algunos de los métodos para capturar el instantáneo del sistema.

  • Copia de seguridad de los Archivos Log

Antes de hacer cualquier cambio, copia los archivos log a otra ubicación. Esto es crucial para entender en qué condición estaba el sistema durante el tiempo del problema. A veces los archivos de registro son la única ventana para ver los estados anteriores del sistema ya que se pierden otras estadísticas de tiempo de ejecución.

  • TCP Dump

Tcpdump es una utilidad de línea de comandos que te permiten capturar y analizar tráfico de red entrante y saliente. Es mayormente usado para ayudar a solucionar problemas de red. Si sientes que el tráfico de sistema está siendo impactado, toma a tcpdump como sigue:

sudo tcpdump -i any -w

# Donde,
# -i any captura tráfico de todas las interfaces
# -w especifica la salida del nombre de archivo

# Para el comando después de unos pocos mins ya que el tamaño del archivo podría incrementar
# usa la extensión de archivo como .pcap

Una vez que el tcpdump es capturado, puedes usar herramientas como Wireshark para analizar el tráfico de forma visual.

Conclusión

Gracias por leer el libro hasta el final. Si lo encontraste útil, considera compartirlo con los demás.

Este libro no termina aquí. Continuaré mejorándolo y agregando nuevos materiales en el futuro. Si encontraste algún problema o te gustaría sugerir alguna mejora, no dudes en abrir una PR / Issue.

¡Manténte conectado y continúa tu jornada de aprendizaje!

Tu jornada con Linux no tiene que terminar aquí. Manténte contectado y lleva tus habilidades al siguiente nivel:

  1. Sígueme en las redes sociales:
  2. X: Comparto contenido útil de forma corta allí. Mi DMs están siempre abiertos.
  3. LinkedIn: Comparto artículos y posts sobre tech allí. Deja una recomendación en LinkedIn y apóyame en habilidades relevantes.
  4. Obtén acceso a contenido exclusivo: Para una ayuda personal y contenido exclusivo ve aquí.

Mis artículos y libros, como este, son parte de mi misión para aumentar el acceso a contenido de calidad para todos. Este libro también estará abierto para ser traducido a otros idiomas. Cada pieza toma mucho tiempo y esfuerzo para escribir. Este libro estará gratuito, para siempre. Si has disfrutado mi trabajo y quieres mantenerme motivado, considera comprarme un café.

Gracias una vez más y, ¡feliz aprendizaje!