Comments

May 2, 2025

Dominando el comando sed en Linux: una guía completa

Introducción

El sedcomando “Editor de Streams” en Linux es una potente utilidad para la manipulación de texto. Permite a los usuarios realizar diversas operaciones, como buscar, reemplazar, insertar y eliminar texto en archivos. Este tutorial ofrece una guía completa para dominar el sedcomando con ejemplos prácticos, explicaciones de sintaxis y casos de uso avanzados.

¿Qué es el comando sed?

El sedcomando es un editor de flujo que procesa texto línea por línea. Esto permite modificar el contenido del archivo sin abrirlo directamente en un editor de texto. Se usa ampliamente en scripts de shell y administración de sistemas para automatizar las tareas de procesamiento de texto.

Características principales de sed

1. Coincidencia y reemplazo de patrones 2. Edición de archivos en el lugar 3. Filtrado y manipulación de texto 4. Compatibilidad con expresiones regulares 5. Operaciones multilínea

Sintaxis básica del sed comando

La sintaxis básica del sedcomando consta de tres componentes principales: las opciones del comando, un script que define las instrucciones de edición y el archivo que se va a procesar.

Esta estructura permite a los usuarios especificar el comportamiento del comando, definir las transformaciones de texto y aplicarlas al archivo deseado.

  1. Opciones de comando : Se utilizan para especificar el comportamiento del comando. Por ejemplo, esta -iopción se utiliza para la edición in situ de archivos, es decir, para sobrescribirlos.
  2. Script : El script define las instrucciones de edición. Puede estar entre comillas simples ( ') o dobles ( "). Puede contener uno o más comandos de edición, separados por punto y coma ( ;).
  3. Archivo de entrada : Este es el archivo que se procesará. Puede ser un solo archivo o una lista de archivos separados por espacios. Si no se especifica ningún archivo, sedse lee desde la entrada estándar.

La sintaxis básica del sedcomando es la siguiente:

sed [options] 'script' file

En esta sintaxis, sedes el comando, [options]son las opciones del comando, 'script'contiene los comandos de edición y filees el archivo que se va a procesar.

sed [options] 'script' file

Lo entenderás mejor con los ejemplos que aparecen a continuación.

sed 's/hello/world/' sample.txt

Esto reemplaza la primera aparición de “hola” con “mundo” en cada línea de sample.txt.

Opciones de uso común ensed

OpciónDescripciónEjemplo
-iEdición in sitused -i 's/old/new/' file.txt
-nSuprimir la impresión automáticased -n '/pattern/p' file.txt
-eEjecutar múltiples comandossed -e 's/old/new/' -e '/pattern/d' file.txt
-fLeer comandos de un archivosed -f script.sed file.txt
-rUtilice expresiones regulares extendidassed -r 's/old/new/' file.txt
-EUtilice expresiones regulares extendidas (similares a -r)sed -E 's/old/new/' file.txt
-zSeparar líneas con carácter NULsed -z 's/old/new/' file.txt
-lEspecifique la longitud de línea para el comando ‘l’sed -l 100 'l' file.txt
-bModo binario (no elimine los caracteres CR)sed -b 's/old/new/' file.txt

Casos de uso más comunes desed

A continuación se muestran algunos de los casos de uso más prácticos del sedcomando.

Primero, creemos un archivo de texto de muestra file1.txty escribamos en él el siguiente texto, para facilitar la comprensión y el seguimiento.

cat > file1.txt

Copie y pegue el siguiente texto:

Linux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Buscar y reemplazar

En el siguiente comando, sse especifica la operación de sustitución y /son delimitadores. /Linux/Es el patrón de búsqueda y Unixes la cadena de reemplazo.

Nota: De forma predeterminada, el sedcomando solo reemplaza la primera aparición del patrón en cada línea y no reemplazará la segunda o tercera aparición en la línea.

sed 's/Linux/Unix/' file1.txt

Este comando reemplaza la primera aparición de “Linux” con “Unix” en cada línea.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Unix are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Reemplazar globalmente en cada línea

La bandera de sustitución /g(reemplazo global) especifica el sedcomando para reemplazar todas las ocurrencias de la cadena en la línea.

sed 's/Linux/Unix/g' file1.txt

Este comando reemplaza todas las apariciones de “Linux” con “Unix” en cada línea.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Edición en el lugar

La opción `-i` permite la edición in situ del archivo. En pocas palabras, lo sobrescribe.

sed -i 's/Linux/Unix/' file1.txt

Este comando edita el archivo en su lugar, reemplazando “Linux” por “Unix” directamente en file1.txt. Sin -i, la inserción solo ocurre en la salida y no modifica el contenido del archivo. Para que el cambio sea persistente, debe usar la -iopción.

Eliminar líneas específicas

sed '2d' file1.txt

Este comando eliminará la segunda línea de file1.txt.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Suprime la -nimpresión automática del espacio de patrón y pes el comando de impresión.

sed -n '1,2p' file1.txt

Este comando imprime las líneas 1 a 2 de file1.txt.

Producción:

OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.

Eliminar líneas que coinciden con un patrón

Las /pattern/líneas coincidentes que contienen el patrón y la dbandera eliminan las líneas coincidentes.

sed '/kernel/d' file1.txt

Este comando eliminará todas las líneas que contengan la palabra “kernel”.

Producción:

OutputOperating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Sustituir con un archivo de respaldo

El siguiente comando reemplazará todas las instancias de “Unix” por “Linux” y creará un archivo de respaldo con el file1.txt.baknombre del archivo anterior antes de reemplazarlo. Esto -i.bakpermite la edición in situ y crea un archivo de respaldo.

sed -i.bak 's/Unix/Linux/g' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Y aquí está el contenido del archivo de respaldo file1.txt.bak.

more file1.txt.bak
OutputUnix is a family of free and open-source operating systems based on the Unix kernel.
Operating systems based on Unix are known as Unix distributions or distros.
Examples include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Unix, and many others.

Reemplazar tabulaciones con espacios

El siguiente comando reemplazará cada tabulación con cuatro espacios. La \tbandera coincide con las tabulaciones y /gsirve para el reemplazo global en toda la línea.

sed 's/\t/    /g' file1.txt

Producción:

Output   Linux is a family of free and open-source operating systems based on the Linux kernel.
Operating systems based on Linux are known as Linux distributions or distros.
Examples     include Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Eliminar líneas vacías

El siguiente comando eliminará todas las líneas vacías de file1.txt. El /^$comando “matches” elimina las líneas vacías y /dlas líneas coincidentes.

sed '/^$/d' file1.txt

Puede editar el file1.txtarchivo usando viel editor de texto y agregar algunas líneas vacías para probar este comando.

El siguiente comando imprime solo las líneas que contienen “Ubuntu”.

sed -n '/Ubuntu/p' file1.txt

La -nopción suprime la impresión automática. /Ubuntu/Coincide con las líneas que contienen el patrón y pse imprimen las líneas coincidentes.

Producción:

OutputExample includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Casos de uso avanzados desed

Esta sección consta de algunos casos de uso avanzados y más complicados del sedcomando.

Insertar texto antes de una línea

El siguiente comando inserta “Este es el texto insertado.” antes de la segunda línea en file1.txt.

sed -i '2i\This is inserted text.' file1.txt

La -iopción es para edición en el lugar y la 2i\bandera inserta texto antes de la segunda línea.

Nota: Sin -i, la inserción solo se produce en la salida y no modifica el contenido del archivo. Para que el cambio sea persistente, debe usar la -iopción con el sedcomando.

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar la enésima ocurrencia de un patrón en una línea

Use los indicadores /1o /2para reemplazar la primera y la segunda aparición de un patrón en una línea. El siguiente comando reemplaza la segunda aparición de la palabra “Linux” por “Unix” en una línea.

sed 's/Linux/Unix/2' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Unix kernel.
This is inserted text.
Operating systems based on Linux are known as Unix distributions or distros.
Examples includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Añadir cadena después de una línea

El siguiente comando añade “Este es el texto añadido” después de la tercera línea file1.txt. Esta -iopción garantiza que los cambios se guarden y 3a\añade el texto después de la tercera línea especificada.

sed -i '3a\This is appended text.' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar una cadena al principio de una línea

La ^<pattern>bandera se usa para coincidir con un patrón específico al inicio de una línea. El siguiente comando reemplaza «Linux» por «Unix» solo si «Linux» aparece al inicio de una línea.

sed 's/^Linux/Unix/' file1.txt

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar cadena al final de una línea

El siguiente comando reemplaza “distros.” por “distributions” solo si aparece al final de una línea. La <pattern>$bandera se usa para hacer coincidir un patrón específico con el final de una línea.

sed 's/distros.$/distributions/' file1.txt

Producción:

OutputLinux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distributions.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazo sin distinción entre mayúsculas y minúsculas

El siguiente comando reemplaza “linux” por “Unix” sin distinguir entre mayúsculas y minúsculas. La Iopción hace que la coincidencia no distinga entre mayúsculas y minúsculas.

sed 's/linux/Unix/I' file1.txt

Extraer líneas entre patrones

El siguiente comando imprime todas las líneas entre “insertado” y “agregado”, inclusive.

sed -n '/inserted/,/appended/p' file1.txt
  1. ,:Operador de rango para hacer coincidir líneas entre dos patrones.
  2. p:Imprime líneas coincidentes.

Y la -nopción de suprimir la impresión automática de líneas.

Producción:

OutputThis is inserted text.
Operating systems based on Linux are known as Linux distributions or distros.
This is appended text.

Procesar varios archivos

El siguiente comando reemplaza “Linux” con “Unix” en ambos file1.txty file2.txtsobrescribe el archivo.

sed -i 's/Linux/Unix/' file1.txt file2.txt

Formato y numeración de líneas no vacías

El siguiente comando agrega números de línea a líneas no vacías en file1.txt.

sed '/./=' file1.txt | sed 'N;s/\n/ /'
  1. /./=: Coincide con líneas que no están vacías y las numera.
  2. N:Agrega la siguiente línea al espacio del patrón.
  3. s/\n/ /: Reemplaza el carácter de nueva línea con un espacio.

Producción:

Output1 Linux is a family of free and open-source operating systems based on the Linux kernel.
2 This is inserted text.
3 Operating systems based on Linux are known as Linux distributions or distros.
4 This is appended text.
5 Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazar cadena en un número de línea específico

Puede restringir el sedcomando para que reemplace la cadena en una línea específica. El siguiente comando reemplaza la cadena “distros” por “distributions” solo en la tercera línea.

sed '3 s/distros/distributions/' file1.txt

Producción:

Linux is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Linux are known as Linux distributions or distributions.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Reemplazo de cadena en un rango de líneas

También puede especificar un rango de números de línea para el sedcomando que reemplaza una cadena. El siguiente comando reemplaza solo las primeras apariciones de “Linux” por “Unix” entre las líneas 1 y 3.

sed '1,3 s/Linux/Unix/' file1.txt

Producción:

OutputUnix is a family of free and open-source operating systems based on the Linux kernel.
This is inserted text.
Operating systems based on Unix are known as Linux distributions or distros.
This is appended text.
Example includes Debian, Ubuntu, Fedora, CentOS, Gentoo, Arch Linux, and many others.

Consideraciones de rendimiento para archivos grandes

Procesar archivos grandes sedpuede consumir muchos recursos, especialmente al trabajar con numerosas operaciones o conjuntos de datos muy grandes. Aquí tienes algunos consejos para optimizar el rendimiento y garantizar un uso eficiente del sedcomando:

1. Usar -npara minimizar la salida innecesaria : Esta -nopción suprime la impresión automática de cada línea y garantiza que solo se muestre la salida deseada. Esto reduce la sobrecarga al trabajar con archivos grandes.

Ejemplo:

sed -n '/pattern/p' largefile.txt

2. Simplifique los scripts : minimice el número de operaciones en un solo comando. Por ejemplo, en lugar de ejecutar varios sedcomandos secuencialmente, combínelos en un solo script para reducir la lectura de archivos.

Ejemplo:

sed -e 's/foo/bar/' -e '/pattern/d' largefile.txt

3. Entrada de flujo con tuberías : al procesar datos de otros comandos o flujos, utilice tuberías para evitar la creación de archivos intermedios y reducir la E/S de disco.

Ejemplo:

cat largefile.txt | sed 's/foo/bar/' > output.txt

4. Evite la edición in situ en archivos grandes : en lugar de modificar directamente archivos grandes, escriba la salida en un nuevo archivo y reemplace el original después de verificar la corrección.

Ejemplo:

sed 's/old/new/' largefile.txt > temp.txt && mv temp.txt largefile.txt

5. Alternativas de referencia : para archivos muy grandes, considere usar herramientas como awk, perl, o grep, que pueden ofrecer un mejor rendimiento para ciertas tareas.

Ejemplo:

awk '{gsub(/old/, "new"); print}' largefile.txt > output.txt

Puede consultar estos tutoriales sobre el comando AWK en Linux y Cómo usar el lenguaje AWK para manipular texto en Linux para obtener más información sobre el uso de awkcomandos en Linux.

Integración con scripts de Shell

El sedcomando se usa comúnmente en scripts de shell para automatizar tareas repetitivas de manipulación de texto. A continuación, un ejemplo:

#!/bin/bash
# Replace all occurrences of "foo" with "bar" in input.txt and save the result
sed 's/foo/bar/g' input.txt > output.txt

Este script procesa input.txty escribe la salida modificada en output.txt.

sedvs otras alternativas

Si bien sedes una herramienta eficaz y ligera para el procesamiento básico de texto, alternativas modernas como awky perlofrecen funciones adicionales, lo que las hace más adecuadas para tareas específicas. A continuación, se detallan las diferencias clave y cuándo usar cada una:

Cuándo utilizarlosed

  • Sustituciones o eliminaciones de texto rápidas y sencillas.
  • Transformaciones basadas en líneas en archivos.
  • Tareas que requieren una sobrecarga de scripting mínima.

Cuándo utilizarloawk

  • Manejo de datos estructurados como archivos CSV o TSV.
  • Realizar cálculos aritméticos junto con el procesamiento de texto.
  • Generar informes formateados a partir de datos de entrada.

Ejemplo:

awk -F, '{print $1, $3}' data.csv

Esto extrae e imprime el primer y tercer campo de un archivo CSV.

Cuándo utilizarloperl

  • Manipulaciones de texto complejas que involucran expresiones regulares avanzadas.
  • Combinando el procesamiento de texto con lógica o condiciones.
  • Cómo escribir scripts compactos pero potentes.

Ejemplo:

perl -pe 's/(error)/WARNING: $1/' logfile.txt

Esto agrega un prefijo “ADVERTENCIA:” a las líneas que contienen la palabra “error”.

Conclusión

Dominar el sedcomando mejora tu capacidad para manipular y procesar texto eficientemente en Linux. Sus potentes funciones y su integración fluida con scripts lo convierten en una herramienta valiosa para tareas de manipulación de texto.

Próximos pasos

Tras dominar los conceptos básicos de sed, podrá aprender técnicas y casos de uso más avanzados. Puede utilizar la siguiente serie de tutoriales sobre sedtemas relacionados que le ayudarán a profundizar su comprensión y mejorar sus habilidades de procesamiento de texto:

  • Conceptos básicos del uso del sededitor de secuencias para manipular texto en Linux
  • Intermedio sed: Manipulación de flujos de texto en un entorno Linux

Estos tutoriales abarcan diversos temas, desde sedoperaciones básicas hasta técnicas más complejas de manipulación de texto. Son un recurso valioso para quienes desean dominar el procesamiento de texto en la línea de comandos.

Preguntas frecuentes

¿Qué es sedun comando en Linux?

El sedcomando “Editor de Flujo” en Linux es una potente herramienta de procesamiento de texto que permite realizar transformaciones básicas de texto en un flujo de entrada (un archivo o la entrada de una canalización). Permite buscar, reemplazar, eliminar e insertar texto, lo que lo hace muy útil para automatizar tareas de manipulación de texto.

¿Cuando utilizarlo sed?

Puede utilizarlo seden los siguientes escenarios:

  • Reemplazo de texto : reemplace palabras, frases o patrones en archivos o transmisiones.
  • Eliminación de texto : elimina líneas o patrones específicos.
  • Edición en el lugar : modifique archivos directamente sin necesidad de abrir un editor de texto.
  • Procesamiento por lotes : realice la misma operación en varios archivos mediante scripts.
  • Inserción/extracción de texto : inserte o extraiga texto específico en archivos estructurados, como archivos de configuración o registros.

¿Cómo utilizarlo sedcorrectamente?

Para utilizarlo sedeficazmente, siga estos pasos:

sed [options] 'command' file
  • command:La sedoperación (por ejemplo, spara sustituir, dpara eliminar).
  • file:El archivo de destino a procesar.

Prueba antes de aplicar en el lugar: primero, ejecute el comando sin la -iopción ‘ para ver el resultado antes de modificar los archivos directamente.

Utilice expresiones regulares: aproveche el soporte de sed para expresiones regulares para hacer coincidir y manipular patrones complejos.

Encadenar varios comandos: utilice ;o -epara ejecutar varios sedcomandos en una sola operación.

¿Cómo usar sed para reemplazar texto?

Para reemplazar texto, utilice el scomando substituir con esta sintaxis:

sed 's/old_text/new_text/' file

Ejemplos:

  • Reemplace la primera aparición de “foo” con “bar” en cada línea:
sed 's/foo/bar/' file.txt
  • Reemplace todas las ocurrencias de “foo” con “bar” globalmente:
sed 's/foo/bar/g' file.txt
  • Reemplazo en el lugar (modifica el archivo directamente):
sed -i 's/foo/bar/g' file.txt

¿Cómo ejecuto un sedcomando?

Puede ejecutar un sedcomando directamente desde la terminal utilizando esta sintaxis básica:

sed 'command' filename

Ejemplo:

Para imprimir líneas que contengan la palabra “error” y reemplazar “error” por “advertencia” en un archivo llamado log.txt:

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

¿Cuál es la diferencia entre los comandos grepy seden Linux?

Característicagrepsed
ObjetivoBuscar patrones en uno o más archivosEditar secuencias de texto
ProducciónImprime líneas que contienen el patrón.Imprime el texto editado
ComportamientoBuscar, filtrarBuscar, Reemplazar, Insertar, Eliminar
Usogrep pattern filesed 'command' file
Buscar y reemplazarSí (limitado)
Edición en el lugarNo
Expresiones regulares
Operaciones multilíneaNo
Filtrado de textoNo
Casos de uso comunesBúsqueda de registros, búsqueda de patrones en el textoEdición de archivos de configuración, reemplazo de texto en varios archivos

Ejemplo:

  • Usando greppara buscar “error” en log.txt:
grep 'error' log.txt
  • Usando sedpara reemplazar “error” con “advertencia” en log.txt:
sed 's/error/warning/g' log.txt

¿Cómo eliminar una línea vacía usando sed?

Para eliminar líneas vacías de un archivo, utilice el siguiente sedcomando:

sed '/^$/d' file.txt

Explicación:

  • ^$: Coincide con líneas vacías (líneas sin caracteres).
  • d:Elimina las líneas coincidentes.

Ejemplo:

Antes de ejecutar el comando, un archivo podría verse así:

line 1

line 2

line 3

Después de ejecutar el comando:

sed '/^$/d' file.txt

La salida será:

Outputline 1
line 2
line 3

Stephen Dove
Comments

April 27, 2025

Cómo crear una aplicación Web usando Flask en Python 3

Introducción

Flask es un marco web de Python pequeño y ligero que proporciona herramientas y funciones útiles que hacen que crear aplicaciones web en Python sea más fácil. Ofrece a los desarrolladores flexibilidad y un marco más accesible para los nuevos desarrolladores ya que puede crear una aplicación web rápidamente usando únicamente un archivo Python. Flask también es extensible y no fuerza una estructura de directorio concreta ni requiere código estándar complicado antes de iniciarse.

Como parte de este tutorial, usará el kit de herramientas Bootstrap para dar estilo a su aplicación, para que sea más atractiva visualmente. Bootstrap le ayudará a incorporar páginas web reactivas en su aplicación web para que también funcione bien en navegadores móviles sin tener que escribir su propio código HTML, CSS y JavaScript para conseguir estos objetivos. El kit de herramientas le permitirá centrarse en aprender cómo funciona Flask.

Flask utiliza el motor de plantillas Jinja para crear dinámicamente páginas HTML usando conceptos Python familiares como variables, bucles, listas, etcétera. Usará estas plantillas como parte de este proyecto.

En este tutorial, creará un pequeño blog web usando Flask y SQLite en Python 3. Los usuarios de la aplicación pueden ver todas las entradas del blog en su base de datos y hacer clic sobre el título de una entrada para ver su contenido, con la capacidad de añadir una nueva publicación a la base de datos y editar o eliminar una entrada existente.

Requisitos previos

Antes de comenzar con esta guía, necesitará lo siguiente:

  • Un entorno de programación Python 3, siguiendo el tutorial para su distribución en la serie Cómo instalar y configurar un entorno de programación local para Python 3 para su equipo local. En este tutorial, llamaremos al directorio de nuestro proyecto flask_blog.
  • Comprender los conceptos de Python 3, como tipos de datos, instrucciones condicionales, bucles for, funciones y otros conceptos similares. Si no está familiarizado con Python, consulte nuestra serie Cómo codificar en Python 3.

Paso 1: Instalar Flask

En este paso, activará su entorno Python e instalará Flask usando el instalador de paquetes pip.

Si aún no ha activado su entorno de programación, asegúrese de que está en el directorio de su proyecto (flask_blog) y utilice el siguiente comando para activar el entorno:

source env/bin/activate

Una vez activado su entorno de programación, su línea de comandos ahora tendrá un prefijo env que puede tener el siguiente aspecto:



Este prefijo es una indicación de que el entorno env está activo actualmente, y puede tener otro nombre dependiendo de cómo lo llamó durante la creación.

Nota: Puede utilizar Git, un sistema de control de versiones, para administrar y realizar un seguimiento de forma efectiva del proceso de desarrollo de su proyecto. Para aprender cómo usar Git, es posible que desee consultar nuestro artículo Introducción a la instalación de Git, uso y ramificaciones.

Si está usando Git, es una buena idea ignorar el recién creado directorio env en su archivo .gitignore para evitar realizar un seguimiento de los archivos no relacionados con el proyecto.

Ahora, instalará los paquetes Python y aislará el código de su proyecto de la instalación del sistema principal de Python. Hará esto usando pip y python.

Para instalar Flask, ejecute el siguiente comando:

pip install flask

Una vez que se complete la instalación, ejecute el siguiente comando para confirmar la instalación:

python -c "import flask; print(flask.__version__)"

Utiliza la interfaz de la línea de comandos python con la opción -c para ejecutar el código Python. A continuación, importa el paquete flask con import flask; luego imprime la versión de Flask, que encontrará a través de la variable flask._version_.

El resultado será un número de versión similar al siguiente:

Output1.1.2

Ha creado la carpeta del proyecto, un entorno virtual, e instalado Flask. Ahora está listo para configurar su aplicación básica.

Paso 2: Crear una aplicación básica

Ahora que tiene su entorno de programación configurado, comenzará a usar Flask. En este paso, creará una pequeña aplicación web dentro de un archivo Python, y la ejecutará para iniciar el servidor, que mostrará cierta información en el navegador.

En su directorio flask_blog, abra un archivo llamado hello.py para su edición; para ello utilice nano o su editor de texto favorito:

nano hello.py

Este archivo hello.py servirá como ejemplo mínimo de cómo gestionar solicitudes HTTP. Dentro, importará el objeto Flask, y creará una función que devuelva una respuesta HTTP. Escriba el siguiente código dentro de hello.py:

flask_blog/hello.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello, World!'

En el bloque de código anterior, primero importa el objeto Flask desde el paquete flask. A continuación lo usará para crear su instancia de aplicación Flask con el nombre app. Pasa la variable especial __name__ que alberga el nombre del módulo Pyhthon actual. Se utiliza para indicar a la instancia dónde está ubicada. Necesitará hacerlo porque Flask configura algunas rutas en segundo plano.

Una vez que cree la instancia app, la utiliza para gestionar las solicitudes web entrantes y enviar respuestas al usuario. @app.route es un decorador que convierte una función Python regular en una función vista de Flask, que convierte el valor de devolución de la función en una respuesta HTTP que se mostrará mediante un cliente HTTP, como un navegador web. Pasa el valor '/' a @app.route() para indicar que esta función responderá a las solicitudes web para la URL /, que es la URL principal.

La función de vista hello() devuelve la cadena 'Hello, World!'​​ como respuesta.

Guarde y cierre el archivo.

Para ejecutar su aplicación web, primero indicará a Flask dónde encontrar la aplicación (el archivo hello.py en su caso) con la variable de entorno FLASK_APP:

export FLASK_APP=hello

A continuación, ejecútela en modo de desarrollo con la variable de entorno FLASK_ENV:

export FLASK_ENV=development

Por último, ejecute la aplicación usando el comando flask run:

flask run

Una vez que la aplicación se esté ejecutando, el resultado será algo similar a esto:

Output * Serving Flask app "hello" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 813-894-335

El resultado anterior tiene varias informaciones, como:

  • El nombre de la aplicación que está ejecutando.
  • El entorno en el cual se ejecuta la aplicación.
  • Debug mode: on significa que el depurador de Flask se está ejecutando. Esto es útil durante el desarrollo porque nos proporciona mensajes de error detallados cuando algo va mal, lo que hace que sea más fácil resolver los problemas.
  • La aplicación se ejecuta localmente sobre la URL http://127.0.0.1:5000/, 127.0.0.1 es la IP que representa el localhost de su equipo y :5000 es el número de puerto.

Abra un navegador y escriba la URL http://127.0.0.1:5000; recibirá la cadena Hello, World! como respuesta. Esto confirma que su aplicación se está ejecutando correctamente.

Advertencia Flask utiliza un servidor web sencillo para presentar nuestra aplicación en un entorno de desarrollo, lo que también significa que el depurador de Flask se ejecuta para hacer que sea más fácil ver los errores. Este servidor de desarrollo no debería usarse en una implementación de producción. Consulte la página Opciones de implementación en la documentación de Flask para obtener más información; también puede consultar este tutorial de Implementación Flask.

Ahora puede dejar el servidor de desarrollo en ejecución en el terminal y abrir otra ventana del terminal. Vaya a la carpeta del proyecto donde está hello.py, active el entorno virtual, establezca las variables del entorno FLASK_ENV y FLASK_APP y continúe a los siguientes pasos. (Estos comandos se han enumerado antes en este paso).

Nota: Cuando abra un nuevo terminal, es importante recordar activar el entorno virtual y configurar las variables de entorno FLASK_ENV y FLASK_APP.

Mientras un servidor de desarrollo de la aplicación de Flask esté ejecutándose, no es posible ejecutar otra aplicación Flask con el mismo comando flask run. Esto es porque flask run utiliza el número de puerto 5000 por defecto, y una vez utilizado, no está disponible para ejecutar otra aplicación, de forma que recibiría un error similar al siguiente:

OutputOSError: [Errno 98] Address already in use

Para resolver este problema, detenga el servidor que se está ejecutando actualmente mediante CTRL+C, luego ejecute flask run de nuevo, o si desea que ambos se ejecuten a la vez, puede pasar un número de puerto diferente al argumento -p; por ejemplo, para ejecutar otra aplicación en el puerto 5001 utilice el siguiente comando:

flask run -p 5001

Ahora tiene una aplicación web Flask pequeña. Ha ejecutado su aplicación y mostrado información en el navegador web. A continuación, utilizará los archivos HTML en su aplicación.

Paso 3: Usar plantillas HTML

Actualmente, su aplicación solo muestra un mensaje sencillo sin HTML. Las aplicaciones web utilizan principalmente HTML para mostrar información al visitante, de forma que ahora trabajará para incorporar archivos HTML en su aplicación, que puede ser mostrada en el navegador web.

Flask proporciona una función de ayuda render_template() que permite el uso del motor de plantillas Jinja. Esto hará que gestionar HTML sea mucho más fácil escribiendo su código HTML en archivos .html, además de utilizar la lógica en su código HTML. Usará estos archivos HTML, (plantillas), para crear todas las páginas de su aplicación, de igual forma que la página principal donde mostrará las entradas actuales del blog, la página de la entrada del blog, la página donde el usuario puede añadir una nueva entrada, etcétera.

En este paso, creará su aplicación Flask principal en un nuevo archivo.

Primero, en su directorio flask_blog, utilice nano o su editor de texto favorito para crear y editar su archivo app.py. Éste albergará todo el código que usará para crear la aplicación de blog:

nano app.py

En este nuevo archivo, importará el objeto Flask para crear una instancia de aplicación Flask, como hizo antes. También importará la función de ayuda render_template() que le permite representar archivos de plantilla HTML que existen en la carpeta templates que está a punto de crear. El archivo tendrá una función de vista única que será responsable de gestionar las solicitudes a la ruta principal /. Añada el siguiente contenido:

flask_blog/app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

La función de vista index() devuelve el resultado de invocar render_template() con index.html como argumento; esto indica a render_template() que busque un archivo llamado index.html en la carpeta templates. La carpeta y el archivo no existen aún, y recibirá un error si ejecutase la aplicación en este momento. De todas formas la va a ejecutar, para que se familiarice con esta excepción que se encuentra comúnmente. Luego lo resolverá creando la carpeta y archivo necesarios.

Guarde el archivo y ciérrelo.

Detenga el servidor de desarrollo en su otro terminal que ejecuta la aplicación hello con CTRL+C.

Antes de ejecutar la aplicación, asegúrese de especificar correctamente el valor para la variable de entorno FLASK_APP, ya que ahora no está usando la aplicación hello.

export FLASK_APP=app
flask run

Al abrir la URL http://127.0.0.1:5000 en su navegador, se mostrará la página del depurador informándole de que no se ha encontrado la plantilla index.html. La línea de código principal en el código responsable de este error se resaltará. En este caso, es la línea return render_template('index.html').

Si hace clic en esta línea, el depurador revelará más código de forma que tenga más contexto para ayudarle a resolver el problema.

El Depurador de Flask

Para solucionar este error, cree un directorio llamado templates dentro de su directorio flask_blog. Dentro de él, abra un archivo llamado index.html para su edición:

mkdir templates
nano templates/index.html

A continuación, añada el siguiente código HTML dentro de index.html:

flask_blog/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskBlog</title>
</head>
<body>
   <h1>Welcome to FlaskBlog</h1>
</body>
</html>

Guarde el archivo y utilice su navegador para navegar a http://127.0.0.1:500 de nuevo, o actualice la página. Esta vez, el navegador debería mostrar el texto Welcome to FlaskBlog en una etiqueta <h1>.

Además de la carpeta templates, las aplicaciones web de Flask también tienen normalmente una carpeta estática para albergar archivos, como los archivos CSS, archivos JavaScript, e imágenes que utiliza la aplicación.

Puede crear un archivo de hoja de estilo style.css para añadir CSS a su aplicación. Primero, cree un directorio llamado static dentro de su directorio flask_blog principal:

mkdir static

Luego cree otro directorio llamado css dentro del directorio static para albergar los archivos .css. Esto normalmente se hace para organizar archivos estáticos en carpetas dedicadas y, en consecuencia, los archivos JavaScript dentro de un directorio llamado js, las imágenes se ponen en un directorio llamado images (o img), etcétera. El siguiente comando creará el directorio css dentro del directorio static:

mkdir static/css

Luego abra un archivo style.css dentro del directorio css para su edición:

nano static/css/style.css

Añada la siguiente regla CSS a su archivo style.css:

flask_blog/static/css/style.css

h1 {
    border: 2px #eee solid;
    color: brown;
    text-align: center;
    padding: 10px;
}

El código CSS añadirá un borde, cambiará el color a marrón, centrará el texto y añadirá un pequeño relleno a las etiquetas <h1>.

Guarde y cierre el archivo.

A continuación, abra el archivo de plantilla index.html para su edición:

nano templates/index.html

Añadirá un enlace al archivo style.css dentro de la sección <head> del archivo de plantilla index.html:

flask_blog/templates/index.html

. . .
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
    <title>FlaskBlog</title>
</head>
. . .

Aquí utiliza la función de ayuda url_for() para generar la ubicación apropiada del archivo. El primer argumento especifica que está vinculando a un archivo estático, y el segundo argumento es la ruta del archivo dentro del directorio estático.

Guarde y cierre el archivo.

Tras actualizar la página de índice de su aplicación, observará que el texto Welcome to FlaskBlog es ahora marrón, está centrado y se encuadra dentro de un borde.

Puede utilizar el lenguaje CSS para dar estilo a la aplicación y hacer que sea más atractiva usando su propio diseño. Sin embargo, si no es un diseñador web, o no está familiarizado con CSS, puede usar el kit de herramientas Bootstrap, que ofrece componentes fáciles de usar para dar estilo a su aplicación. En este proyecto, usaremos Bootstrap.

Quizá haya imaginado que crear otra plantilla HTML significará repetir la mayoría del código HTML que ya escribió en la plantilla index.html. Puede evitar la repetición innecesaria de código con la ayuda de un archivo de plantilla base, desde el cual heredarán todos sus archivos HTML. Consulte Herencia de plantillas en Jinja para obtener más información.

Para crear una plantilla base, primero cree un archivo llamado base.html dentro de su directorio templates:

nano templates/base.html

Escriba el siguiente código en su plantilla base.html:

flask_blog/templates/base.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>{% block title %} {% endblock %}</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-md navbar-light bg-light">
        <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
            <li class="nav-item active">
                <a class="nav-link" href="#">About</a>
            </li>
            </ul>
        </div>
    </nav>
    <div class="container">
        {% block content %} {% endblock %}
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

Guarde y cierre el archivo una vez que haya terminado de editarlo.

La mayor parte del código en el bloque anterior es HTML estándar y el código necesario para Bootstrap. Las etiquetas <meta> proporcionan información para el navegador web, la etiqueta <link> enlaza los archivos CSS de Boostrap y las etiquetas <script> son enlaces a código JavaScript que permite algunas funciones adicionales de Boostrap; consulte la documentación de Boostrap para obtener más información.

Sin embargo, las siguientes partes resaltadas son específicas para el motor de plantillas Jinja:

  • {% block title %} {% endblock %}: un bloque que sirve como marcador de posición para un título. Más adelante lo usará en otras plantillas para dar un título personalizado a cada página de su aplicación sin tener que reescribir toda la sección <head> cada vez.
  • {{ url_for('index')}: una invocación de función que devolverá la URL para la función de vista index(). Esto es diferente a la invocación anterior url_for() que utilizó para vincular a un archivo CSS estático, porque solo requiere un argumento, que es el nombre de la función de vista, y enlaza a la ruta asociada con la función en vez de con un archivo estático.
  • {% block content %} {% endblock %}: otro bloque que se sustituirá por contenido dependiendo de la plantilla secundaria (plantillas que heredan de base.html) que lo anulará.

Ahora que tiene una plantilla base, puede aprovecharla usando la herencia. Abra el archivo index.html:

nano templates/index.html

Sustituya su contenido con lo siguiente:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
{% endblock %}

En esta nueva versión de la plantilla index.html, utiliza la etiqueta {% extends %} para que herede de la plantilla base.html. Luego la extiende sustituyendo el bloque content en la plantilla base con lo que está dentro del bloque content en el bloque de código anterior.

Este bloque content contiene una etiqueta <h1> con el texto Welcome to FlaskBlog dentro de un bloque title, que a su vez sustituye el bloque title original en la plantilla base.html con el texto Welcome to FlaskBlog. De esta forma, puede evitar repetir el mismo texto dos veces, ya que funciona como título para la página y como encabezado que aparece bajo la barra de navegación heredada de la plantilla base.

La herencia de plantillas también le ofrece la capacidad de reutilizar el código HTML que tiene en otras plantillas (base.html en este caso), sin tener que repetirlo cada vez que sea necesario.

Guarde y cierre el archivo y actualice la página de índice en su navegador. Verá su página con una barra de navegación y un título con estilo.

Página de índice con Bootstrap

Utilizó plantillas HTML y archivos estáticos en Flask. También ha utilizado Bootstrap para comenzar a refinar el aspecto de su página y una plantilla base para evitar la repetición del código. En el siguiente paso, configurará una base de datos que almacenará los datos de su aplicación.

Paso 4: Configurar la base de datos

En este paso, configurará una base de datos para almacenar los datos, es decir, las entradas del blog para su aplicación. También completará la base de datos con algunas entradas de ejemplo.

Usará un archivo de base de datos SQLite para guardar sus datos porque el módulo sqlite3, que utilizaremos para interactuar con la base de datos, está disponible en la biblioteca Python. Para obtener más información sobre SQLite, consulte este tutorial.

Primero, ya que los datos de SQLite se guardan en tablas y columnas, y ya que sus datos principalmente son entradas de blog, primero deberá crear una tabla llamada posts con las columnas necesarias. Creará un archivo .sql que contiene comandos SQL para crear la tabla posts con algunas columnas. A continuación usará este archivo para crear la base de datos.

Abra un archivo llamado schema.sql dentro de su directorio flask_blog:

nano schema.sql

Escriba los siguientes comandos SQL dentro de este archivo:

flask_blog/schema.sql

DROP TABLE IF EXISTS posts;

CREATE TABLE posts (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    title TEXT NOT NULL,
    content TEXT NOT NULL
);

Guarde y cierre el archivo.

El primer comando SQL es DROP TABLE IF EXISTS posts;, esto elimina cualquier tabla que exista llamada posts para que no tenga un comportamiento confuso. Observe que esto eliminará todo el contenido que tenga en la base de datos siempre que utilice estos comandos SQL, de forma que asegúrese de no escribir ningún contenido importante en la aplicación web hasta que haya terminado con este tutorial y experimente con el resultado final. A continuación, CREATE TABLE posts se utiliza para crear la tabla posts con las siguientes columnas:

  • id: es un entero que representa una clave primaria. La base de datos asignará un valor único para cada entrada (es decir, una entrada blog).
  • created: la hora en que se creó la entrada de blog. NOT NULL significa que esta columna no debería estar vacía y el valor DEFAULT es el valor CURRENT_TIMESTAMP, que es la hora en la cual la entrada se añadió a la base de datos. Igual que el id, no necesita especificar un valor para esta columna, y que se completará automáticamente.
  • title: el título de la entrada.
  • content: el contenido de la entrada.

Ahora que tiene un esquema SQL en el archivo schema.sql, lo usará para crear la base de datos usando un archivo Python que generará un archivo base de datos .db de SQLite. Abra un archivo llamado init_db.py dentro del directorio flask_blog usando su editor preferido:

nano init_db.py

Y luego añada el siguiente código.

flask_blog/init_db.py

import sqlite3

connection = sqlite3.connect('database.db')


with open('schema.sql') as f:
    connection.executescript(f.read())

cur = connection.cursor()

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('First Post', 'Content for the first post')
            )

cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
            ('Second Post', 'Content for the second post')
            )

connection.commit()
connection.close()

Primero importe el módulo sqlite3 y luego abra una conexión con el archivo de la base de datos llamada database.db, que se creará una vez que ejecute el archivo Python. Luego utilice la función open() para abrir el archivo schema.sql. A continuación, ejecute su contenido utilizando el método executescript() que ejecuta múltiples instrucciones SQL a la vez, lo que creará la tabla posts. Crea un objeto Cursor que le permite usar su método execute() para ejecutar dos instrucciones SQL INSERT para permitir dos entradas de blog en su tabla posts. Finalmente, confirma los cambios y cierra la conexión.

Guarde y cierre el archivo y a continuación ejecútelo en el terminal usando el comando python:

python init_db.py

Una vez que el archivo termine su ejecución, aparecerá un nuevo archivo llamado database.db en su directorio flask_blog. Esto significa que la configurado correctamente su base de datos.

En el siguiente paso, recuperará las entradas que insertó en su base de datos y las mostrará en la página de inicio de su aplicación.

Paso 5: Mostrar todas las entradas

Ahora que ha configurado su base de datos, puede modificar la función de vista index() para mostrar todas las entradas que tiene en su base de datos.

Abra el archivo app.py para realizar las siguientes modificaciones:

nano app.py

Para su primera modificación, importará el módulo sqlite3 en la parte superior del archivo:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template

. . .

A continuación, creará una función que cree una conexión de base de datos y la devolverá. Añádala directamente tras las importaciones:

flask_blog/app.py

. . .
from flask import Flask, render_template

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

. . .

Esta función get_db_connection() abra una conexión con el archivo de base de datos database.db, y luego establece el atributo row_factory a sqlite3. Row para poder tener acceso basado en nombre a las columnas. Esto significa que la conexión con la base de datos devolverá filas que se comportan como diccionarios Python regulares. Por último, la función devuelve el objeto de conexión conn que usará para acceder a la base de datos.

Tras definir la función get_db_connection, modifique la función index() para que tenga el siguiente aspecto:

flask_blog/app.py

. . .

@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

En esta nueva versión de la función index(), primero abre una conexión de base de datos usando la función get_db_connection() que definió antes. A continuación, ejecuta una consulta SQL para seleccionar todas las entradas de la tabla post. Implementa el método fetchall() para recuperar todas las filas del resultado de la consulta. Esto devolverá una lista de las entradas que insertó en la base de datos en el paso anterior.

Cierra la conexión con la base de datos usando el método close() y devuelve el resultado de representar la plantilla index.html. También pasará el objeto posts como argumento, que contiene los resultados que obtuvo de la base de datos; esto le permitirá acceder a las entradas del blog en la plantilla index.html.

Con estas modificaciones implementadas, guarde y cierre el archivo app.py.

Ahora que ha pasado las entradas que recuperó de la base de datos a la plantilla index.html, puede usar un bucle for para mostrar cada entrada en su página de índice.

Abra el archivo index.html:

nano templates/index.html

A continuación, modifíquelo como sigue:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="#">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <hr>
    {% endfor %}
{% endblock %}

Aquí, la sintaxis {% for post in posts %} es un bucle for Jinja, que es similar a un bucle for Python, excepto que tiene que ser cerrado posteriormente con la sintaxis {% endfor %}. Utiliza esta sintaxis para realizar un bucle sobre cada elemento en la lista posts que se pasó por la función index() en la línea return render_template('index.html', posts=posts). Dentro de este bucle for, muestra el título de la entrada en un encabezado <h2> dentro de una etiqueta <a> (más tarde utilizará esta etiqueta para vincular con cada entrada individualmente).

Muestra el título utilizando un delimitador variable literal ({{ ... }}). Recuerde que post será un objeto similar a un diccionario, para que pueda acceder al título de la entrada con post['title']​​​. También muestra la fecha de creación de la entrada usando el mismo método.

Una vez que haya terminado de editar el archivo, guarde y ciérrelo. Luego navegue a la página de índice en su navegador. Verá las dos entradas que añadió a la base de datos en su página.

Página de índice con entradas mostradas

Ahora que ha modificado la función de vista index() para mostrar todas las entradas que tiene en la base de datos en la página de inicio de su aplicación, pasará a mostrar cada entrada en una única página y permitirá que los usuarios vinculen a cada entrada individual.

Paso 6: Mostrar una entrada única

En este paso, creará una nueva ruta Flask con una función de vista y una nueva plantilla HTML para mostrar una entrada de blog individual por su ID.

Al final de este paso, la URL http://127.0.0.1:5000/1 será una página que muestra la primera entrada (porque tiene el ID 1). La URL http://127.0.0.1:5000/ID mostrará la entrada con el número ID asociado si existe.

Abra app.py para su edición:

nano app.py

Ya que necesitará obtener una entrada de blog por su ID de la base de datos en múltiples ubicación más adelante en este proyecto, creará una función independiente llamada get_post(). Puede invocarla pasándole un ID y recibiendo la entrada de blog asociada con el ID proporcionado, o hacer que Flask responsa con un mensaje 404 Not Found si la entrada de blog no existe.

Para responder con una página 404, deberá importar la función abort() desde la biblioteca Wekzeug, que se instaló junto con Flask en la parte superior del archivo:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template
from werkzeug.exceptions import abort

. . .

A continuación, añada la función get_post() justo tras la función get_db_connection() que creó en el paso anterior:

flask_blog/app.py

. . .

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn


def get_post(post_id):
    conn = get_db_connection()
    post = conn.execute('SELECT * FROM posts WHERE id = ?',
                        (post_id,)).fetchone()
    conn.close()
    if post is None:
        abort(404)
    return post

. . .

Esta nueva función tiene el argumento post_id que determina qué entrada de blog recuperar.

Dentro de la función, utiliza la función get_db_connection() para abrir una conexión de base de datos y ejecutar una consulta SQL para obtener la entada de blog asociada con el valor post_id dado. Añade el método fetchone() para obtener el resultado y almacenarlo en la variable post. Luego, cierre la conexión. Si la variable post tiene el valor None, lo que significa que no se ha encontrado ningún resultado en la base de datos, utiliza la función abort() que importó anteriormente para responder con un código de error 404 y la función terminará la ejecución. Si, sin embargo, se encuentra una entrada, devuelve el valor de la variable post.

A continuación, añada la siguiente función de vista al final del archivo app.py:

flask_blog/app.py

. . .

@app.route('/<int:post_id>')
def post(post_id):
    post = get_post(post_id)
    return render_template('post.html', post=post)

En esta nueva función de vista, añade una regla de variable <int:post_id> para especificar que la parte tras la barra (/) es un entero positivo (marcado con el conversor int) que necesita para acceder en su función de vista. Flask reconoce esto y pasa su valor al argumento de palabra clave post_id de su función de vista post(). A continuación, utiliza la función get_post() para obtener la entrada de blog asociada con el ID especificado y almacenar el resultado en la variable post, que pasa por una plantilla post.html que pronto creará.

Guarde el archivo app.py y abra un nuevo archivo de plantilla post.html para su edición:

nano templates/post.html

Escriba el siguiente código en este nuevo archivo post.html. Esto será similar al archivo index.html, excepto que solo mostrará una única entrada además de mostrar el contenido de la entrada:

flask_blog/templates/post.html

{% extends 'base.html' %}

{% block content %}
    <h2>{% block title %} {{ post['title'] }} {% endblock %}</h2>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <p>{{ post['content'] }}</p>
{% endblock %}

Añade el bloque title que definió en la plantilla base.html para hacer que el título de la página refleje el título de la entrada que se muestra en un encabezado <h2> al mismo tiempo.

Guarde y cierre el archivo.

Ahora puede navegar a la siguiente URL para ver las dos entradas que tiene en su base de datos, junto con una página que indica al usuario que no se encontró la entrada del blog solicitada (ya que no hay una entrada con el número de ID 3 hasta ahora):

http://127.0.0.1:5000/1
http://127.0.0.1:5000/2
http://127.0.0.1:5000/3

Volviendo a la página de índice, creará cada enlace al título de la entrada a su página respectiva. Hará esto usando la función url_for(). Primero, abra la plantilla index.html para su edición:

nano templates/index.html

A continuación cambie el valor del atributo href de # a {{ url_for('post', post_id=post['id']) }} de forma que el bucle for tendrá el siguiente aspecto:

flask_blog/templates/index.html

{% for post in posts %}
    <a href="{{ url_for('post', post_id=post['id']) }}">
        <h2>{{ post['title'] }}</h2>
    </a>
    <span class="badge badge-primary">{{ post['created'] }}</span>
    <hr>
{% endfor %}

Aquí, pasa 'post' a la función url_for() como primer argumento. Este es el nombre de la función de vista post() y ya que acepta un argumento post_id, le da el valor post['id']. La función url_for() devolverá la URL adecuada para cada entrada según su ID.

Guarde y cierre el archivo.

Los enlaces en la página de índice ahora funcionarán como se espera. Con esto, ha terminado de crear la parte de la aplicación responsable de mostrar las entradas de blog en su base de datos. A continuación, añadirá la capacidad de crear, editar y eliminar entradas de blog en su aplicación.

Paso 7: Modificar entradas

Ahora que ha terminado de mostrar las entradas de blog que están presentes en la base de datos en la aplicación web, deberá permitir a los usuarios de su aplicación escribir nuevas entradas de blog y añadirlas a la base de datos, editar las existentes y eliminar las entradas de blog innecesarias.

Crear una nueva entrada

Hasta este momento, tiene una aplicación que muestra las entradas en su base de datos pero no ofrece ninguna forma de añadir una nueva entrada a menos que conecte directamente con la base de datos SQLite y añada una manualmente. En esta sección, creará una página sobre la cual podrá crear una entrada proporcionando su título y contenido.

Abra el archivo app.py para su edición:

nano app.py

Primero, importará lo siguiente desde el marco Flask:

  • El objeto global request para acceder a los datos de solicitud entrantes que se enviarán a través de un formato HTML.
  • La función url_for() para generar URLs.
  • La función flash() para mostrar un mensaje cuando se procesa una solicitud.
  • La función redirect() para redirigir al cliente a una ubicación diferente.

Añada las importaciones a su archivo de la siguiente forma:

flask_blog/app.py

import sqlite3
from flask import Flask, render_template, request, url_for, flash, redirect
from werkzeug.exceptions import abort

. . .

La función flash() almacena los mensajes mostrados en la sesión del navegador del cliente, lo que requiere configurar una clave secreta. Esta clave secreta se utiliza para proteger las sesiones, lo que permite a Flask recordar la información de una solicitud a la otra, como pasar desde la nueva página de entrada a la página de índice. El usuario puede acceder a la información almacenada en la sesión, pero no puede modificarla a menos que tenga la clave secreta, de forma que nunca permita que nadie acceda a la clave secreta. Consulte la documentación de Flask para sesiones para obtener más información.

Para establecer una_ clave_ secreta, añadirá una configuración SECRET_KEY a su aplicación a través del objeto app.config. Añádala directamente siguiendo la definición app antes de definir la función de vista index():

flask_blog/app.py

. . .
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your secret key'


@app.route('/')
def index():
    conn = get_db_connection()
    posts = conn.execute('SELECT * FROM posts').fetchall()
    conn.close()
    return render_template('index.html', posts=posts)

. . .

Recuerde que la clave secreta debería ser una cadena aleatoria larga.

Tras establecer una clave secreta, creará una función de vista que mostrará una plantilla que muestra un formulario que puede completar para crear una nueva entrada de blog. Añada esta nueva función en la parte inferior del archivo:

flask_blog/app.py

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    return render_template('create.html')

Esto crea una ruta /create que acepta las solicitudes GET y POST. Las solicitudes GET se aceptan por defecto. También acepta las solicitudes POST que se envía el navegador cuando se envían formularios. Pasará un tuple con los tipos de solicitudes aceptadas al argumento methods del decorador @app.route().

Guarde y cierre el archivo.

Para crear la plantilla, abra un archivo llamado create.html dentro de su carpeta templates:

nano templates/create.html

Añada el siguiente código dentro de este nuevo archivo:

flask_blog/templates/create.html

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Create a New Post {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title"
               placeholder="Post title" class="form-control"
               value="{{ request.form['title'] }}"></input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
{% endblock %}

La mayor parte de este código es HTML estándar. Mostrará un cuadro de entrada para el título de la entrada, un área de texto para el contenido de la entrada y un botón para enviar el formulario.

El valor de la entrada del título de la entrada es {{ request.form['title'] }},​​​ y el área de texto tiene el valor {{ request.form['content'] }}. Esto se hace para que los datos que introduce no se pierdan si algo sale mal. Por ejemplo, si escribe una entrada larga y olvida darle un título, se mostrará un mensaje que le informa de que el título es necesario. Esto sucederá sin perder la entrada que escribió ya que se almacenará en el objeto global request al que tiene acceso en sus plantillas.

Ahora, con el servidor de desarrollo en ejecución, utilice su navegador para navegar a la ruta /create:

http://127.0.0.1:5000/create

Verá una página Create a New Post con un cuadro para un título y contenido:

Crear una nueva página de entrada

Este formulario envía una solicitud POST a su función de vista create(). Sin embargo, aún no hay ningún código para gestionar una solicitud POST en la función, de forma que no sucederá nada tras completar el formulario y enviarlo.

Gestionará la solicitud POST entrante cuando se envía un formulario. Lo hará dentro de la función de vista create(). Puede gestionar por separado la solicitud POST comprobando el valor de request.method. Cuando su valor se establece a 'POST', significa que la solicitud es una solicitud POST. Luego extraerá los datos enviados, los validará y los insertará en su base de datos.

Abra el archivo app.py para su edición:

nano app.py

Modifique la función de vista create() para que tenga exactamente el siguiente aspecto:

flask_blog/app.py

. . .

@app.route('/create', methods=('GET', 'POST'))
def create():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)',
                         (title, content))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('create.html')

En la instrucción if asegura que el código que le sigue solo se ejecuta cuando la solicitud es una solicitud POST a través de la comparativa request.method == 'POST'.

A continuación, extrae el título enviado y el contenido desde el objeto request.form que le proporciona acceso a los datos del formulario en la solicitud. Si no se proporciona el título, la condición if not title se cumplirá, mostrando un mensaje al usuario informándole de que el título es obligatorio. Si, por otro lado, se proporciona el título, abrirá una conexión con la función get_db_connection() e insertará el título y el contenido que recibió en la tabla posts.

Luego confirma los cambios en la base de datos y cierra la conexión. Tras añadir la entrada de blog a la base de datos, redirige al cliente a la página de índice usando la función redirect() pasándole la URL generada por la función url_for() con el valor 'index' como argumento.

Guarde y cierre el archivo.

Ahora, navegue a la ruta /create usando su navegador web:

http://127.0.0.1:5000/create

Complete el formulario con un título y algo de contenido. Una vez que envíe el formulario, verá la nueva entrada listada en la página de índice.

Por último, mostrará los mensajes generados y añadirá un enlace a la barra de navegación en la plantilla base.html para tener un acceso fácil a esta nueva página. Abra el archivo de plantilla:

nano templates/base.html

Edite el archivo añadiendo una nueva etiqueta <li> tras el enlace About dentro de la etiqueta <nav>. A continuación, añada un nuevo bucle for directamente sobre el bloque content para mostrar los mensajes generados bajo la barra de navegación. Estos mensajes están disponibles en la función especial get_flashed_messages() que Flask ofrece:

flask_blog/templates/base.html

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a class="navbar-brand" href="{{ url_for('index')}}">FlaskBlog</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
        <li class="nav-item">
            <a class="nav-link" href="#">About</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{{url_for('create')}}">New Post</a>
        </li>
        </ul>
    </div>
</nav>
<div class="container">
    {% for message in get_flashed_messages() %}
        <div class="alert alert-danger">{{ message }}</div>
    {% endfor %}
    {% block content %} {% endblock %}
</div>

Guarde y cierre el archivo. La barra de navegación ahora tendrá un elemento New Post que enlaza a la ruta /create.

Editar una entrada

Para que un blog esté actualizado, deberá poder editar sus entradas existentes. Esta sección le guiará en la creación de una nueva página en su aplicación para simplificar el proceso de editar una entrada.

Primero, añadirá una nueva ruta al archivo app.py. Su función de vista recibirá el ID de la entrada que debe ser editada, la URL estará en el formato /post_id/edit con la variable post_id siendo el ID de la entrada. Abra el archivo app.py para su edición:

nano app.py

A continuación, añada la siguiente función de vista edit() al final del archivo. Editar una entrada existente es similar a crear una nueva, de forma que esta función de vista será similar a la función de vista create():

flask_blog/app.py

. . .

@app.route('/<int:id>/edit', methods=('GET', 'POST'))
def edit(id):
    post = get_post(id)

    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title:
            flash('Title is required!')
        else:
            conn = get_db_connection()
            conn.execute('UPDATE posts SET title = ?, content = ?'
                         ' WHERE id = ?',
                         (title, content, id))
            conn.commit()
            conn.close()
            return redirect(url_for('index'))

    return render_template('edit.html', post=post)

La entrada que edita viene determinada por la URL y Flask pasará el número de ID a la función edit() a través del argumento id. Añade este valor a la función get_post() para recuperar la entrada asociada con el ID proporcionado desde la base de datos. Los nuevos datos vendrán en una solicitud POST, que se gestiona dentro de la condición if request.method == 'POST'.

Igual que cuando creó una nueva entrada, primero extrae los datos del objeto request.form, luego muestra un mensaje si el título tiene un valor vacío, de lo contrario, abre una conexión con la base de datos. Luego actualiza la tabla posts estableciendo un nuevo título y nuevo contenido donde el ID de la entrada en la base de datos es igual al ID que estaba en la URL.

En el caso de una solicitud GET, representa una plantilla edit.html pasando la variable post que alberga el valor devuelto de la función get_post(). Usará esto para mostrar el título existente y el contenido en la página de edición.

Guarde y cierre el archivo, y cree una nueva plantilla edit.html:

nano templates/edit.html

Escriba el siguiente código dentro de este nuevo archivo:

flask_blog/templates/edit.html

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Edit "{{ post['title'] }}" {% endblock %}</h1>

<form method="post">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title" placeholder="Post title"
               class="form-control"
               value="{{ request.form['title'] or post['title'] }}">
        </input>
    </div>

    <div class="form-group">
        <label for="content">Content</label>
        <textarea name="content" placeholder="Post content"
                  class="form-control">{{ request.form['content'] or post['content'] }}</textarea>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</form>
<hr>
{% endblock %}

Guarde y cierre el archivo.

Este código sigue el mismo patrón excepto por la sintaxis {{ request.form['title'] or post['title'] }} y {{ request.form['content'] or post['content'] }}. Esto muestra los datos guardados en la solicitud si existe, de lo contrario, muestra los datos de la variable post que se pasó a la plantilla que contiene los datos actuales de la base de datos.

Ahora, navegue a la siguiente URL para editar la primera entrada:

http://127.0.0.1:5000/1/edit

Verá una página Edit “First Post”.

Editar la página de una entrada

Edite la entrada y envíe el formulario, luego asegúrese de que la entrada se ha actualizado.

Ahora necesita añadir un enlace que apunte a la página de edición para cada entrada en la página de índice. Abra el archivo de plantilla index.html:

nano templates/index.html

Edite el archivo para que tenga exactamente el siguiente aspecto:

flask_blog/templates/index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>
    {% for post in posts %}
        <a href="{{ url_for('post', post_id=post['id']) }}">
            <h2>{{ post['title'] }}</h2>
        </a>
        <span class="badge badge-primary">{{ post['created'] }}</span>
        <a href="{{ url_for('edit', id=post['id']) }}">
            <span class="badge badge-warning">Edit</span>
        </a>
        <hr>
    {% endfor %}
{% endblock %}

Guarde y cierre el archivo.

Aquí añade una etiqueta <a> para enlazar a la función de vista edit(), pasando el valor post['id'] al enlace para editar la página de cada entrada con el enlace Edit.

Eliminar una entrada

A veces, no es necesario que una entrada siga estando disponible públicamente, y por eso la funcionalidad de eliminar una entrada es crucial. En este paso, añadirá la funcionalidad de eliminación a su aplicación.

Primero, añadirá una nueva ruta /ID/delete que acepta solicitudes POST, de forma similar a la función de vista edit(). Su nueva función de vista delete() recibirá el ID de la entrada que será eliminada de la URL. Abra el archivo app.py:

nano app.py

Añada la siguiente función de vista en la parte inferior del archivo:

flask_blog/app.py

# ....

@app.route('/<int:id>/delete', methods=('POST',))
def delete(id):
    post = get_post(id)
    conn = get_db_connection()
    conn.execute('DELETE FROM posts WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    flash('"{}" was successfully deleted!'.format(post['title']))
    return redirect(url_for('index'))

Esta función de vista solo acepta solicitudes POST. Esto significa que navegar a la ruta /ID/delete en su navegador devolverá un error porque los navegadores web van de forma predeterminada a las solicitudes GET.

Sin embargo, puede acceder a esta ruta mediante un formulario que envía una solicitud POST pasando el ID de la entrada que desea eliminar. La función recibirá el valor de ID y lo usará para obtener la entrada de la base de datos con la función get_post().

A continuación, abrirá una conexión de base de datos y ejecutará un comando SQL DELETE FROM para eliminar la entrada. Confirma el cambio en la base de datos y cierra la conexión mientras muestra un mensaje para informar al usuario de que la entrada se eliminó correctamente y redirigirlo a la página de índice.

Observe que no reproduce un archivo de plantilla. Esto es porque añadirá un botón Delete a la página de edición.

Abra el archivo de plantilla edit.html:

nano templates/edit.html

Luego, añada la siguiente etiqueta <form> tras la etiqueta <hr> y directamente antes de la línea {% endblock %}:

flask_blog/templates/edit.html

<hr>

<form action="{{ url_for('delete', id=post['id']) }}" method="POST">
    <input type="submit" value="Delete Post"
            class="btn btn-danger btn-sm"
            onclick="return confirm('Are you sure you want to delete this post?')">
</form>

{% endblock %}

Utiliza el método confirm() para mostrar un mensaje de confirmación antes de enviar la solicitud.

Ahora, navegue de nuevo a la página de edición de una entrada de blog e intente eliminarla:

http://127.0.0.1:5000/1/edit

Al final de este paso, el código fuente de su proyecto tendrá el aspecto del código en esta página.

Con esto, los usuarios de su aplicación pueden escribir nuevas entradas de blog y añadirlas a la base de datos, editar entradas y eliminar las entradas existentes.

Conclusión

Este tutorial ha introducido los conceptos esenciales del marco Flask Python. Ha aprendido a crear una pequeña aplicación web, ejecutarla en un servidor de desarrollo y a permitir al usuario proporcionar datos personalizados a través de parámetros URL y formularios web. También utilizó el motor de plantillas Jinja para reutilizar los archivos HTMP y usar lógica en ellos. Al final de este tutorial, tendrá un blog web completamente funcional que interactúa con una base de datos SQLite para crear, mostrar, editar y eliminar entradas de blog usando el lenguaje Python y las consultas SQL.

Puede seguir desarrollando esta aplicación añadiendo autenticación del usuario de forma que solo los usuarios registrados puedan crear o modificar entradas de blog. También puede añadir comentarios y etiquetas para cada entrada de blog, y añadir subidas de archivos para dar a los usuarios la capacidad de incluir imágenes en la entrada del blog. Consulte la documentación de Flask para obtener más información.

Flask cuenta con muchas extensiones Flask creadas por la comunidad. A continuación verá una lista de extensiones que quizá quiera considerar usar para que su proceso de desarrollo sea más fácil:

  • Flask-Login: gestiona la sesión del usuario y el inicio y cierre de sesión, además de recordar a los usuarios con sesión iniciada.
  • Flask-SQLAlchemy: simplifica el uso de Flask con SQLAlchemy, un kit de herramientas Python SQL y un Asignador relacional de objetos para interactuar con bases de datos SQL.
  • Flask-Mail: ayuda con la tarea de enviar mensajes de correo electrónico en su aplicación Flask.

Stephen Dove
Comments

April 27, 2025

Cómo instalar MySQL en Ubuntu 22.04

Introducción

MySQL es un sistema de gestión de bases de datos de código abierto, comúnmente instalado como parte de la popular pila LAMP (Linux, Apache, MySQL, PHP/Python/Perl). Implementa el modelo relacional y utiliza el Lenguaje de Consulta Estructurado (más conocido como SQL) para gestionar sus datos.

Este tutorial explicará cómo instalar MySQL versión 8.0 en un servidor Ubuntu 22.04. Al completarlo, dispondrá de una base de datos relacional funcional que podrá usar para crear su próximo sitio web o aplicación.

Implemente una base de datos MySQL con un solo clic usando las bases de datos administradas de IsnHosting . Deje que DigitalOcean se encargue del escalado, el mantenimiento y las actualizaciones de su base de datos.

Prerrequisitos

Para seguir este tutorial, necesitarás:

Paso 1: Instalación de MySQL

En Ubuntu 22.04, puedes instalar MySQL usando el repositorio de paquetes APT. Al momento de escribir este artículo, la versión de MySQL disponible en el repositorio predeterminado de Ubuntu es la 8.0.28.

Para instalarlo, actualice el índice de paquetes en su servidor si no lo ha hecho recientemente:

sudo apt update

Luego instala el mysql-serverpaquete:

sudo apt install mysql-server

Asegúrese de que el servidor se esté ejecutando mediante el systemctl startcomando:

sudo systemctl start mysql.service

Estos comandos instalarán e iniciarán MySQL, pero no le solicitarán que establezca una contraseña ni realice ningún otro cambio de configuración. Dado que esto hace que su instalación de MySQL sea insegura, abordaremos este tema a continuación.

Paso 2: Configuración de MySQL

Para nuevas instalaciones de MySQL, deberá ejecutar el script de seguridad incluido en el sistema de gestión de bases de datos. Este script modifica algunas de las opciones predeterminadas menos seguras, como impedir el inicio de sesión remoto como root y eliminar usuarios de muestra.

Advertencia : A partir de julio de 2022, se producirá un error al ejecutar el mysql_secure_installationscript sin ninguna configuración adicional. Esto se debe a que este script intentará establecer una contraseña para la cuenta raíz de MySQL de la instalación, pero, por defecto en las instalaciones de Ubuntu, esta cuenta no está configurada para conectarse con contraseña.

Antes de julio de 2022, este script fallaba silenciosamente tras intentar establecer la contraseña de la cuenta raíz y continuar con el resto de las indicaciones. Sin embargo, al momento de escribir este artículo, el script devolverá el siguiente error después de ingresar y confirmar una contraseña:

Output ... Failed! Error: SET PASSWORD has no significance for user 'root'@'localhost' as the authentication method used doesn't store authentication data in the MySQL server. Please consider using ALTER USER instead if you want to change authentication parameters.

New password:

Esto llevará al script a un bucle recursivo del que sólo podrás salir cerrando la ventana de tu terminal.

Dado que el mysql_secure_installationscript realiza otras acciones útiles para mantener la seguridad de su instalación de MySQL, se recomienda ejecutarlo antes de empezar a usar MySQL para administrar sus datos. Sin embargo, para evitar este bucle recursivo, primero deberá ajustar la autenticación de su usuario root de MySQL.

Primero, abra el indicador de MySQL:

sudo mysql

A continuación, ejecute el siguiente ALTER USERcomando para cambiar el método de autenticación del usuario root a uno que utilice contraseña. El siguiente ejemplo cambia el método de autenticación a mysql_native_password:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Después de realizar este cambio, salga del indicador de MySQL:

exit

Después de esto, puedes ejecutar el mysql_secure_installationscript sin problemas.

Ejecute el script de seguridad con sudo:

sudo mysql_secure_installation

Esto le guiará a través de una serie de indicaciones donde podrá realizar cambios en las opciones de seguridad de su instalación de MySQL. La primera le preguntará si desea configurar el complemento Validar contraseña, que permite comprobar la seguridad de las contraseñas de los nuevos usuarios de MySQL antes de considerarlas válidas.

Si elige configurar el complemento Validar contraseña, cualquier usuario de MySQL que cree que se autentique con una contraseña deberá tener una contraseña que cumpla con la política que seleccione:

OutputSecuring the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: Y

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG:
 2

Independientemente de si decide configurar el complemento Validar contraseña, el siguiente paso será establecer una contraseña para el usuario root de MySQL . Ingrese y confirme una contraseña segura de su elección:

OutputPlease set the password for root here.


New password:

Re-enter new password:

Tenga en cuenta que aunque haya establecido una contraseña para el usuario root de MySQL, este usuario no está configurado actualmente para autenticarse con una contraseña al conectarse al shell de MySQL.

Si usaste el complemento Validar contraseña, recibirás información sobre la seguridad de tu nueva contraseña. El script te preguntará si deseas continuar con la contraseña que acabas de ingresar o si deseas ingresar una nueva. Si estás satisfecho con la seguridad de la contraseña que acabas de ingresar, presiona Enter Ypara continuar con el script:

OutputEstimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Desde allí, puede presionar Yy luego ENTERaceptar los valores predeterminados para todas las preguntas subsiguientes. Esto eliminará algunos usuarios anónimos y la base de datos de prueba, deshabilitará los inicios de sesión remotos como root y cargará estas nuevas reglas para que MySQL respete inmediatamente los cambios realizados.

Nota: Una vez completado el script de seguridad, puede volver a abrir MySQL y cambiar el método de autenticación del usuario root al predeterminado. auth_socketPara autenticarse como usuario root de MySQL con una contraseña, ejecute este comando:

mysql -u root -p

Luego vuelva a utilizar el método de autenticación predeterminado usando este comando:

ALTER USER 'root'@'localhost' IDENTIFIED WITH auth_socket;

Esto significará que podrás volver a conectarte a MySQL como tu usuario root usando el sudo mysqlcomando.

Una vez completado el script, su instalación de MySQL estará protegida. Ahora puede crear un usuario de base de datos dedicado con el cliente MySQL.

Paso 3: Creación de un usuario MySQL dedicado y concesión de privilegios

Tras la instalación, MySQL crea una cuenta de usuario root que puede usar para administrar su base de datos. Este usuario tiene privilegios completos sobre el servidor MySQL, lo que significa que tiene control total sobre cada base de datos, tabla, usuario, etc. Por ello, se recomienda evitar usar esta cuenta fuera de las funciones administrativas. Este paso describe cómo usar el usuario root de MySQL para crear una nueva cuenta de usuario y otorgarle privilegios.

En sistemas Ubuntu con MySQL 5.7 (y versiones posteriores), el usuario root de MySQL se autentica mediante el auth_socketcomplemento por defecto, en lugar de una contraseña. Este complemento requiere que el nombre del usuario del sistema operativo que invoca el cliente MySQL coincida con el nombre del usuario MySQL especificado en el comando, por lo que debe invocarlo mysqlcon sudoprivilegios para acceder al usuario root de MySQL:

sudo mysql

Nota: Si instaló MySQL con otro tutorial y habilitó la autenticación con contraseña para root , deberá usar un comando diferente para acceder al shell de MySQL. El siguiente comando ejecutará su cliente MySQL con privilegios de usuario normales, y solo obtendrá privilegios de administrador en la base de datos al autenticarse:

mysql -u root -p

Una vez que tenga acceso al prompt de MySQL, puede crear un nuevo usuario con una CREATE USERinstrucción. Estas instrucciones siguen la siguiente sintaxis general:

CREATE USER 'username'@'host' IDENTIFIED WITH authentication_plugin BY 'password';

Después de CREATE USER, se especifica un nombre de usuario. A esto le sigue inmediatamente un @signo y el nombre de host desde el que se conectará este usuario. Si solo planea acceder a este usuario localmente desde su servidor Ubuntu, puede especificar localhost. No siempre es necesario escribir el nombre de usuario y el host entre comillas simples, pero esto puede ayudar a prevenir errores.

Tiene varias opciones para elegir el plugin de autenticación de usuario. El auth_socketplugin mencionado anteriormente puede ser práctico, ya que proporciona una seguridad sólida sin requerir que los usuarios válidos introduzcan una contraseña para acceder a la base de datos. Sin embargo, también impide las conexiones remotas, lo que puede complicar la interacción de programas externos con MySQL.

Como alternativa, puede omitir por completo esta parte de la sintaxis para que el usuario se autentique con el complemento predeterminado de MySQL. La documentación de MySQL recomienda este complemento para usuarios que desean iniciar sesión con contraseña debido a sus sólidas funciones de seguridad.WITH authentication_plugincaching_sha2_password

Ejecute el siguiente comando para crear un usuario que se autentique con [ nombre de usuario caching_sha2_password]. Asegúrese de usar sammysu nombre de usuario preferido y passworduna contraseña segura de su elección:

CREATE USER 'sammy'@'localhost' IDENTIFIED BY 'password';

Nota : Existe un problema conocido con algunas versiones de PHP que causa problemas con caching_sha2_password. Si planea usar esta base de datos con una aplicación PHP (por ejemplo, phpMyAdmin), le recomendamos crear un usuario que se autentique con el complemento anterior, aunque aún seguro mysql_native_password:

CREATE USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Si no está seguro, siempre puede crear un usuario que se autentique con caching_sha2_pluginy luego ALTERmás tarde con este comando:

ALTER USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Tras crear el nuevo usuario, puede otorgarle los privilegios correspondientes. La sintaxis general para otorgar privilegios de usuario es la siguiente:

GRANT PRIVILEGE ON database.table TO 'username'@'host';

El valor en esta sintaxis de ejemplo define las acciones que el usuario puede realizar en el `and` especificado . Puede otorgar varios privilegios al mismo usuario en un solo comando separándolos con una coma. También puede otorgar privilegios globales a un usuario introduciendo asteriscos ( ) PRIVILEGEen lugar de los nombres de las bases de datos y las tablas. En SQL, los asteriscos son caracteres especiales que se utilizan para representar “todas” las bases de datos o tablas.databasetable*

A modo de ejemplo, el siguiente comando otorga a un usuario privilegios globales sobre CREATE, ALTER, y DROPbases de datos, tablas y usuarios, así como la capacidad de acceder a INSERT, UPDATEy DELETEdatos de cualquier tabla del servidor. También le otorga la capacidad de consultar datos con SELECT, crear claves foráneas con la REFERENCESpalabra clave y realizar FLUSHoperaciones con el RELOADprivilegio . Sin embargo, solo debe otorgar a los usuarios los permisos que necesiten, así que puede ajustar los privilegios de sus usuarios según sea necesario.

Puede encontrar la lista completa de privilegios disponibles en la documentación oficial de MySQL .

Ejecute esta GRANTdeclaración, reemplazándola sammycon el nombre de su propio usuario MySQL, para otorgarle estos privilegios a su usuario:

GRANT CREATE, ALTER, DROP, INSERT, UPDATE, INDEX, DELETE, SELECT, REFERENCES, RELOAD on *.* TO 'sammy'@'localhost' WITH GRANT OPTION;

Tenga en cuenta que esta declaración también incluye WITH GRANT OPTION. Esto permitirá que su usuario de MySQL otorgue los permisos que tenga a otros usuarios del sistema.

Advertencia : algunos usuarios pueden querer otorgarle a su usuario MySQL el ALL PRIVILEGESprivilegio que les proporcionará amplios privilegios de superusuario similares a los privilegios del usuario root , de la siguiente manera:

GRANT ALL PRIVILEGES ON *.* TO 'sammy'@'localhost' WITH GRANT OPTION;

No se deben conceder privilegios tan amplios , ya que cualquiera con acceso a este usuario MySQL tendrá control total sobre todas las bases de datos del servidor.

A continuación, se recomienda ejecutar el FLUSH PRIVILEGEScomando. Esto liberará la memoria almacenada en caché por el servidor como resultado de las CREATE USERinstrucciones anteriores GRANT:

FLUSH PRIVILEGES;

Luego puedes salir del cliente MySQL:

exit

En el futuro, para iniciar sesión como su nuevo usuario MySQL, deberá utilizar un comando como el siguiente:

mysql -u sammy -p

La -pbandera hará que el cliente MySQL le solicite la contraseña de su usuario MySQL para poder autenticarse.

Por último, probemos la instalación de MySQL.

Paso 4: Prueba de MySQL

Independientemente de cómo lo hayas instalado, MySQL debería haberse iniciado automáticamente. Para comprobarlo, comprueba su estado.

systemctl status mysql.service

La salida será similar a la siguiente:

Output● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-04-11 16:04:39 UTC; 2h 36min ago
    Process: 2593 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
   Main PID: 2601 (mysqld)
     Status: "Server is operational"
      Tasks: 38 (limit: 1119)
     Memory: 354.3M
        CPU: 19.944s
     CGroup: /system.slice/mysql.service
             └─2601 /usr/sbin/mysqld

Si MySQL no se está ejecutando, puedes iniciarlo con sudo systemctl start mysql.

Para una comprobación adicional, puede intentar conectarse a la base de datos mediante la mysqladminherramienta, que es un cliente que permite ejecutar comandos administrativos. Por ejemplo, este comando indica que debe conectarse con el usuario MySQL llamado sammy ( ), solicitar una contraseña ( ) y devolver la versión. Asegúrese de cambiar el nombre de su usuario MySQL dedicado e introducir su contraseña cuando se le solicite:-u sammy-psammy

sudo mysqladmin -p -u sammy version

A continuación se muestra un ejemplo de la salida:

Outputmysqladmin  Ver 8.0.28-0ubuntu4 for Linux on x86_64 ((Ubuntu))
Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Server version          8.0.28-0ubuntu4
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/run/mysqld/mysqld.sock
Uptime:                 2 hours 31 min 57 sec

Threads: 2  Questions: 25  Slow queries: 0  Opens: 160  Flush tables: 3  Open tables: 79  Queries per second avg: 0.000

Esto significa que MySQL está en funcionamiento.

Conclusión

Ya tiene una configuración básica de MySQL instalada en su servidor. Aquí tiene algunos ejemplos de los pasos a seguir:

  • Configurar una pila LAMP o una pila LEMP
  • Practique la ejecución de consultas con SQL
  • Administre su instalación de MySQL con phpMyAdmin

Stephen Dove
Comments

April 27, 2025

Introducción a la terminología, interfaces y protocolos de redes

Introducción

Comprender las redes es fundamental para cualquier persona que administre un servidor. No solo es esencial para que sus servicios estén en línea y funcionen sin problemas, sino que también le proporciona la información necesaria para diagnosticar problemas.

Este artículo ofrece una descripción general de algunos conceptos comunes de redes. Analizaremos la terminología, los protocolos comunes y las responsabilidades y características de las diferentes capas de red.

Esta guía es independiente del sistema operativo, pero debería ser muy útil al implementar funciones y servicios que utilizan redes en su servidor.

Glosario de redes

Primero, definiremos algunos términos comunes que verá a lo largo de esta guía y en otras guías y documentación sobre redes.

Estos términos se ampliarán en las secciones correspondientes que siguen:

  • Conexión : En redes, una conexión se refiere a la información relacionada que se transfiere a través de una red. Generalmente, una conexión se establece antes de la transferencia de datos (siguiendo los procedimientos establecidos en un protocolo) y puede desestructurarse al final de la transferencia.
  • Paquete : Un paquete es la unidad más pequeña que se transfiere intencionalmente a través de una red. Al comunicarse a través de una red, los paquetes son los sobres que transportan los datos (en fragmentos) de un extremo a otro.

Los paquetes tienen una sección de encabezado que contiene información sobre el paquete, incluyendo el origen y el destino, las marcas de tiempo, los saltos de red, etc. La sección principal del paquete contiene los datos que se transfieren. A veces se denomina cuerpo o carga útil.

  • Interfaz de red : Una interfaz de red puede referirse a cualquier tipo de interfaz de software con hardware de red. Por ejemplo, si tiene dos tarjetas de red en su computadora, puede controlar y configurar cada interfaz de red asociada a ellas individualmente.

Una interfaz de red puede estar asociada a un dispositivo físico o ser la representación de una interfaz virtual. El dispositivo de bucle invertido, una interfaz virtual disponible en la mayoría de los entornos Linux para conectarse a la misma máquina, es un ejemplo de ello.

  • LAN : LAN significa «red de área local». Se refiere a una red o a una parte de ella que no es accesible públicamente a internet. Una red doméstica o de oficina es un ejemplo de LAN.
  • WAN : WAN significa “red de área extensa”. Se refiere a una red mucho más extensa que una LAN. Si bien WAN es el término relevante para describir redes grandes y dispersas en general, generalmente se refiere a Internet en su conjunto.

Si se dice que una interfaz está conectada a la WAN, generalmente se supone que es accesible a través de Internet.

  • Protocolo : Un protocolo es un conjunto de reglas y estándares que definen un lenguaje que los dispositivos pueden usar para comunicarse. Existe una gran cantidad de protocolos ampliamente utilizados en redes, y a menudo se implementan en diferentes capas.

Algunos protocolos de bajo nivel son TCP, UDP, IP e ICMP. Algunos ejemplos conocidos de protocolos de capa de aplicación, basados ​​en estos protocolos de bajo nivel, son HTTP (para acceder a contenido web), SSH y TLS/SSL.

  • Puerto : Un puerto es una dirección en una sola máquina que puede vincularse a un programa específico. No es una interfaz ni una ubicación física, pero permite que su servidor se comunique mediante más de una aplicación.
  • Cortafuegos : Un cortafuegos es un programa que decide si se debe permitir el tráfico entrante o saliente de un servidor. Un cortafuegos suele funcionar creando reglas que determinan qué tipo de tráfico es aceptable en qué puertos. Generalmente, los cortafuegos bloquean los puertos que no utiliza una aplicación específica en un servidor.
  • NAT : NAT significa Traducción de Direcciones de Red. Es una forma de reempaquetar y enviar las solicitudes entrantes a un servidor de enrutamiento a los dispositivos o servidores correspondientes en una LAN. Esto se suele implementar en redes LAN físicas para enrutar las solicitudes a través de una dirección IP a los servidores backend necesarios.
  • VPN : VPN significa red privada virtual. Es un medio para conectar redes LAN independientes a través de internet, manteniendo la privacidad. Se utiliza para conectar sistemas remotos como si estuvieran en una red local, a menudo por razones de seguridad.

Encontrará muchos otros términos, y esta lista no es exhaustiva. Explicaremos otros términos según sea necesario. En este punto, debería comprender algunos conceptos generales que nos permitirán abordar mejor los temas que se tratarán a continuación.

Capas de red

Si bien las redes suelen analizarse en términos de topología de manera horizontal, entre hosts su implementación se realiza en capas de manera vertical dentro de cualquier computadora o red determinada.

Esto significa que existen múltiples tecnologías y protocolos que se complementan para que la comunicación funcione. Cada capa superior abstrae un poco más los datos sin procesar.

También le permite aprovechar las capas inferiores de nuevas maneras sin tener que invertir tiempo y energía para desarrollar los protocolos y aplicaciones que manejan esos tipos de tráfico.

El lenguaje que usamos para describir cada esquema de capas varía significativamente según el modelo utilizado. Independientemente del modelo utilizado para describir las capas, la ruta de los datos es la misma.

A medida que los datos se envían desde una máquina, comienzan en la parte superior de la pila y se filtran hacia abajo. En el nivel más bajo, se produce la transmisión real a otra máquina. En este punto, los datos vuelven a ascender a través de las capas de la otra computadora.

Cada capa tiene la capacidad de agregar su propio “envoltorio” alrededor de los datos que recibe de la capa adyacente, lo que ayudará a las capas que vienen después a decidir qué hacer con los datos cuando se entregan.

Modelo TCP/IP

El modelo TCP/IP, más conocido como el conjunto de protocolos de Internet, es un modelo de capas ampliamente adoptado. Define cuatro capas independientes:

  • Aplicación : En este modelo, la capa de aplicación se encarga de crear y transmitir datos de usuario entre aplicaciones. Las aplicaciones pueden estar en sistemas remotos y deben funcionar como si estuvieran localmente para el usuario final. Se dice que esta comunicación se realiza entre pares .
  • Transporte : La capa de transporte es responsable de la comunicación entre procesos. Este nivel de red utiliza puertos para gestionar diferentes servicios.
  • Internet : La capa de Internet se utiliza para transportar datos entre nodos de una red. Esta capa conoce los puntos finales de las conexiones, pero no se ocupa de la conexión real necesaria para llegar de un lugar a otro. Las direcciones IP se definen en esta capa como una forma de acceder a sistemas remotos de forma direccionable.
  • Enlace : La capa de enlace implementa la topología de la red local, lo que permite que la capa de Internet presente una interfaz direccionable. Establece conexiones entre nodos vecinos para el envío de datos.

Como puede ver, el modelo TCP/IP es abstracto y fluido. Esto popularizó su implementación y le permitió convertirse en la forma dominante de categorizar las capas de red.

Interfaces

Las interfaces son puntos de comunicación de red para su computadora. Cada interfaz está asociada a un dispositivo de red físico o virtual.

Normalmente, su servidor tendrá una interfaz de red configurable para cada tarjeta de Internet Ethernet o inalámbrica que tenga.

Además, definirá una interfaz de red virtual denominada “loopback” o interfaz localhost. Esta se utiliza para conectar aplicaciones y procesos de un mismo ordenador con otros. En muchas herramientas, se denomina “lo”.

Muchas veces, los administradores configuran una interfaz para atender el tráfico a Internet y otra interfaz para una LAN o red privada.

En centros de datos con redes privadas habilitadas (incluidos los Droplets de DigitalOcean), su VPS tendrá dos interfaces de red. La interfaz “eth0” se configurará para gestionar el tráfico de internet, mientras que la interfaz “eth1” se comunicará con una red privada.

Protocolos

Las redes funcionan mediante la superposición de varios protocolos diferentes. De esta forma, un mismo dato puede transmitirse utilizando múltiples protocolos encapsulados entre sí.

Comenzaremos con protocolos implementados en las capas de red inferiores y avanzaremos hasta llegar a protocolos con mayor abstracción.

Control de acceso al medio

El control de acceso al medio es un protocolo de comunicaciones que se utiliza para distinguir dispositivos específicos. Cada dispositivo debe recibir una dirección MAC (dirección de control de acceso al medio ) única y codificada durante su fabricación, lo que lo diferencia de cualquier otro dispositivo en internet.

Direccionar el hardware mediante la dirección MAC le permite hacer referencia a un dispositivo mediante un valor único incluso cuando el software superior puede cambiar el nombre de ese dispositivo específico durante la operación.

El direccionamiento MAC es uno de los únicos protocolos de la capa de enlace de bajo nivel con el que probablemente interactuará de manera regular.

Propiedad intelectual

El protocolo IP es uno de los protocolos fundamentales que permiten el funcionamiento de internet. Las direcciones IP son únicas en cada red y permiten que las máquinas se direccionen entre sí a través de ella. Se implementa en la capa de internet del modelo TCP/IP.

Las redes pueden conectarse entre sí, pero el tráfico debe enrutarse al cruzar los límites de la red. Este protocolo asume una red poco fiable y múltiples rutas hacia el mismo destino, entre las que puede cambiar dinámicamente.

Existen diversas implementaciones del protocolo. La implementación más común actualmente son las direcciones IPv4, que siguen el patrón [número] 123.123.123.123, aunque las direcciones IPv6, que también siguen el patrón [número] 2001:0db8:0000:0000:0000:ff00:0042:8329, están ganando popularidad debido a la cantidad limitada de direcciones IPv4 disponibles.

ICMP

ICMP significa Protocolo de Mensajes de Control de Internet. Se utiliza para enviar mensajes entre dispositivos para indicar su disponibilidad o errores. Estos paquetes se utilizan en diversas herramientas de diagnóstico de red, como pingy traceroute.

Normalmente, los paquetes ICMP se transmiten cuando un tipo de paquete diferente detecta un problema. Se utilizan como mecanismo de retroalimentación para las comunicaciones de red.

TCP

TCP significa protocolo de control de transmisión. Se implementa en la capa de transporte del modelo TCP/IP y se utiliza para establecer conexiones fiables.

TCP es uno de los protocolos que encapsula datos en paquetes. Luego, los transfiere al extremo remoto de la conexión mediante los métodos disponibles en las capas inferiores. En el otro extremo, puede comprobar si hay errores, solicitar el reenvío de ciertos fragmentos y reensamblar la información en un único fragmento lógico para enviarlo a la capa de aplicación.

El protocolo establece una conexión antes de la transferencia de datos mediante un sistema denominado protocolo de enlace de tres vías. Este protocolo permite que ambos extremos de la comunicación reconozcan la solicitud y acuerden un método para garantizar la fiabilidad de los datos.

Una vez enviados los datos, la conexión se interrumpe mediante un protocolo de enlace de cuatro vías similar.

TCP es el protocolo elegido para muchos de los usos más populares de Internet, incluidos WWW, SSH y el correo electrónico.

UDP

UDP significa protocolo de datagramas de usuario. Es un protocolo complementario popular de TCP y también se implementa en la capa de transporte.

La diferencia fundamental entre UDP y TCP es que UDP ofrece una transferencia de datos poco fiable. No verifica la recepción de datos en el otro extremo de la conexión. Esto podría parecer perjudicial, y para muchos propósitos lo es. Sin embargo, también es fundamental para ciertas funciones.

Dado que no es necesario esperar la confirmación de la recepción de los datos ni forzar su reenvío, UDP es mucho más rápido que TCP. No establece una conexión con el host remoto, simplemente envía datos sin confirmación.

Al ser una transacción directa, resulta útil para comunicaciones como la consulta de recursos de red. Además, no mantiene un estado, lo que la hace ideal para transmitir datos desde una máquina a varios clientes en tiempo real. Esto la hace ideal para VoIP, juegos y otras aplicaciones que no admiten retrasos.

HTTP

HTTP significa protocolo de transferencia de hipertexto. Es un protocolo definido en la capa de aplicación que constituye la base de la comunicación en la web.

HTTP define varios verbos que indican al sistema remoto qué se solicita. Por ejemplo, GET, POST y DELETE interactúan con los datos solicitados de forma diferente. Para ver un ejemplo de las diferentes solicitudes HTTP en acción, consulte Cómo definir rutas y métodos de solicitud HTTP en Express .

DNS

DNS significa sistema de nombres de dominio. Es un protocolo de capa de aplicación que proporciona un mecanismo de nombres intuitivo para los recursos de internet. Es lo que vincula un nombre de dominio a una dirección IP y permite acceder a sitios web por su nombre en el navegador.

SSH

SSH significa Secure Shell. Es un protocolo cifrado implementado en la capa de aplicación que permite comunicarse con un servidor remoto de forma segura. Muchas tecnologías adicionales se basan en este protocolo gracias a su cifrado de extremo a extremo y su ubicuidad.

Hay muchos otros protocolos que no hemos cubierto y que son igualmente importantes. Sin embargo, esto debería brindarle una buena visión general de algunas de las tecnologías fundamentales que hacen posible internet y las redes.

Conclusión

En este punto, debería estar familiarizado con la terminología de redes y comprender cómo se comunican los diferentes componentes. Esto le ayudará a comprender otros artículos y la documentación de su sistema.

A continuación, para ver un ejemplo de alto nivel del mundo de la lectura, puede leer Cómo realizar solicitudes HTTP en Go .

Stephen Dove
Comments

April 27, 2025

Cómo usar Vim para la edición avanzada de texto plano o código en un VPS

Introducción


Vim, una mejora del vieditor de texto clásico, es extremadamente potente para editar código y texto plano. Aunque al principio pueda parecer obtuso y difícil, es una de las formas más eficientes de editar texto gracias a su sintaxis de comandos similar a la del lenguaje.

En un artículo anterior, explicamos cómo instalar Vim y realizar ediciones básicas . En este documento, abordaremos temas más avanzados que pueden ayudar a demostrar la versatilidad de la edición.

Asumiremos que ha instalado vim y está familiarizado con los comandos básicos de movimiento y edición analizados en el artículo vinculado anteriormente.

Navegación avanzada


Antes de comenzar con nuevo material, repasemos un poco la navegación que aprendimos en el artículo anterior:

  • Movimientos básicos
    • h: izquierda
    • l: derecha
    • j: abajo
    • k: arriba
  • Otros movimientos
    • gg: parte superior del documento
    • G: parte inferior del documento o número de línea si se coloca un número delante de G
    • w: siguiente palabra
    • e: fin de palabra
    • 0: comienzo de línea
    • $: fin de línea

Como pueden ver, ya tenemos bastantes comandos de movimiento a nuestra disposición. Sin embargo, también podemos dirigir el movimiento de otras maneras.

Podemos mover el cursor a diferentes áreas en la porción actualmente visible de la página usando estos comandos:

  • H : Mueve el cursor a la parte superior de la página visible actualmente (piensa en “alto”)
  • M : Mueve el cursor al centro de la página visible actualmente
  • L : Mueve el cursor a la parte inferior de la página visible actualmente (piensa en “abajo”)

Si queremos mover la página en lugar del cursor (como en el desplazamiento), podemos utilizar estos comandos:

  • CTRL-D : Av Pág
  • CTRL-U : Re Pág
  • CTRL-E : desplazarse hacia abajo una línea
  • CTRL-Y : desplazarse hacia arriba una línea

También podemos navegar por bloques lógicos de información. Esto puede ser útil si se escribe texto normal en lugar de código. Son similares a los comandos de navegación por palabras y líneas.

  • ) : Mover al inicio de la siguiente oración
  • ( : Mover al inicio de la última oración
  • } : Mover al inicio del siguiente párrafo (delimitado por una línea en blanco)
  • { : Mover al inicio del último párrafo (delimitado por una línea en blanco)

También puedes definir tus propios puntos en el archivo para saltar a ellos. Puedes establecerlos marksen cualquier punto del archivo. Luego, puedes referenciar esas marcas para saltar a ese punto o pasarlo a un comando que acepte movimientos:

  • m : Escribir “m” seguido de una letra crea una marca de referencia con esa letra.
    • Las letras minúsculas son específicas del documento actual, mientras que las letras mayúsculas solo se pueden usar una vez (se pueden usar para saltar a secciones en diferentes documentos).
  • : La comilla simple seguida de una letra de marca (previamente definida con la “m” como arriba), moverá el cursor al comienzo de la línea que contiene esa marca.
  • ` : La comilla invertida seguida de una letra de marca moverá el cursor a la posición exacta de la marca.

Estos comandos permiten colocar una marca y luego retirar, eliminar o formatear el área definida entre la posición actual y la marca. Esto permite un control muy preciso de las opciones de edición.

Cómo gestionar documentos


A menudo, al trabajar, ya sea en un proyecto de software o en un trabajo académico, es necesario poder referenciar varios documentos a la vez. Vim ofrece diferentes maneras de hacerlo, según cómo se desee trabajar.

Cómo gestionar los buffers


Una forma de gestionar varios archivos es mediante buffers. Los búferes suelen representar un archivo abierto para edición. Son básicamente todo lo que vim tiene abierto actualmente y a lo que puede acceder fácilmente.

Abrimos varios archivos con vim de la siguiente manera:

vim file1 file2 file3

Cada uno de estos archivos se abre en su propio buffer. Actualmente, solo podemos ver el primer archivo.

Podemos ver qué buffers tenemos disponibles escribiendo :buffers.

:buffers

:buffers
  1 %a  "file1"             line 1
  2     "file2"             line 0
  3     "file3"             line 0
Press ENTER or type command to continue

Si deseamos consultar el siguiente búfer, podemos escribir :bn. Esto cambiará al siguiente búfer. De igual forma, podemos cambiar a un búfer por número (en la primera columna de arriba) o por nombre, escribiendo b. Esto funciona incluso si el nombre del archivo está incompleto.

A continuación se muestran algunos de los comandos para administrar buffers:

  • :buffers : Lista de buffers disponibles
  • :ls : Lo mismo que arriba
  • :bn : Cambiar al siguiente búfer
  • :bp : Cambiar al búfer anterior
  • :bfirst : Cambiar al primer búfer
  • :blast : Cambiar al último búfer
  • :bdelete : Elimina el búfer actual
  • :badd : Abre un nuevo buffer con el nombre de archivo que sigue
  • :e : Edita otro archivo en un nuevo buffer y cámbialo.

Cómo administrar Windows


Un mecanismo de control independiente que Vim ofrece para gestionar múltiples archivos es el concepto de windowso views. Esto permite dividir el área de edición actual en diferentes ventanas para poder ver varios búferes simultáneamente.

Para dividir el espacio de trabajo actual en ventanas independientes, puede escribir :splito :sp. Esto abre una nueva ventana sobre la actual y la enfoca. Puede cambiar el búfer que se muestra en la nueva ventana usando los comandos de búfer mostrados arriba.

Aquí hay algunos comandos que podemos usar para crear y administrar ventanas:

  • :sp : Divide la ventana actual en dos. Inicialmente, se mostrará el mismo búfer en cada ventana.
    • Anteponga un número a la “sp” para establecer la nueva altura de la ventana.
  • :vs : Divide la ventana actual verticalmente. Inicialmente, se mostrará el mismo búfer en cada ventana.
    • Anteponga un número al “vs” para establecer el nuevo ancho de la ventana.
  • CTRL-ww : Cambiar el foco a la siguiente ventana
  • CTRL-w(movimiento) : Cambia el foco a la ventana en la dirección (h,j,k,l) ​​indicada
  • CTRL-wc : Cerrar la ventana actual
  • CTRL-w+ : Aumentar el tamaño de la ventana actual
  • CTRL-w- : Disminuir el tamaño de la ventana actual
  • CTRL-w= : Establecer todas las ventanas con el mismo tamaño
  • #CTRL-w_ : Establece la altura al tamaño indicado por el “#” precedente
  • :only : Cierra todas las ventanas excepto la actual
  • CTRL-wn : Abre una nueva ventana con un nuevo búfer

Cómo administrar pestañas


Un tercer concepto para gestionar múltiples documentos en Vim es el de tabs. A diferencia de muchos programas, en Vim, las pestañas pueden contener ventanas, no al revés. Las pestañas pueden contener ventanas, que actúan como ventanas gráficas en los búferes.

Podemos gestionar el diseño de la ventana de cada pestaña por separado. Para crear pestañas, podemos usar el :tabnewcomando para abrir una nueva pestaña.

Algunas formas sencillas de administrar las pestañas son:

  • :tabnew : Abrir nueva pestaña
  • :tabclose : Cerrar la pestaña actual
  • :tabn : Cambiar a la siguiente pestaña
  • gt : Cambiar a la siguiente pestaña
  • :tabp : Cambiar a la pestaña anterior
  • gT : Cambiar a la pestaña anterior
  • :tab ball : Abre todos los buffers en pestañas individuales
  • :tabs : Lista todas las pestañas disponibles

Al cambiar entre búferes, ventanas y pestañas, a veces resulta confuso saber qué archivo estás viendo. Una forma rápida de averiguar el nombre del archivo es escribir:

  • CTRL-g : Muestra el nombre del archivo actual

Comandos específicos del documento


Dependiendo del tipo de documentos con los que esté tratando, vim tiene ciertas funcionalidades que pueden ayudarlo.

Texto sin formato


Si edita documentos de texto sin formato, Vim puede ayudarle de diversas maneras. Una de las funciones esenciales para esta función es el corrector ortográfico.

Para activar la corrección ortográfica en vim, puedes escribir:

:set spell

Para configurar el idioma que se está utilizando, puede escribir:

:set spelllang=[language abbreviation]

Ahora, se revisará la ortografía de su documento. La línea ondulada normal aparecerá debajo de las palabras mal escritas. Así es como se usa.

Para saltar hacia adelante y hacia atrás entre palabras mal escritas, escriba:

]s    # Jump to next mistake
[s    # Jump to previous mistake

Una vez que el cursor esté sobre una palabra mal escrita, podrá ver sugerencias ortográficas escribiendo:

z=

Esto le mostrará una lista de posibles coincidencias. Puede seleccionar la opción que desee eligiendo el número asociado o pulsar ENTER para dejar la palabra como está.

Si desea marcar una palabra como correcta , puede agregarla a una lista de ortografía. Vim mantiene dos listas de ortografía: una normal y una temporal que se usará en la sesión actual.

Para agregar la palabra a la lista de palabras “buenas”, utilice uno de estos comandos:

zg    # Adds word to regular dictionary
zG    # Adds word to the current session dictionary

Si agrega una palabra accidentalmente, puede eliminarla yendo a la palabra y escribiendo:

zug   # Remove word from regular dictionary
zuG   # Remove word from the current session dictionary

Si a menudo tiene que escribir palabras o frases largas, puede agregar una abreviatura.

Si escribimos :abseguido de una abreviatura y una expansión, vim ingresará la expansión siempre que escribamos la abreviatura seguida de un espacio.

Por ejemplo, si somos puristas y seguimos el ejemplo de Richard Stallman de corregir cualquier uso de “Linux” con “GNU/Linux”, podemos crear una abreviatura que lo haga automáticamente:

:ab Linux GNU/Linux

Ahora, cuando escribimos “Linux”, vim sustituirá automáticamente “GNU/Linux”.

Linux is an operating system.

Cambios en:

GNU/Linux is an operating system.

Sin embargo, si nos encontramos hablando específicamente del kernel, donde sólo la palabra Linux sería apropiada, podemos cancelar la expansión escribiendo CTRL-Vantes de escribir el espacio.

GNU/Linux is an operating system with Linux(CTRL-V) as a kernel.

Si ya no queremos utilizar esta abreviatura, podemos eliminarla con este comando:

:una Linux 

Ahora nuestro “Linux” seguirá siendo “Linux”.

Otra cosa que podrías tener que hacer de vez en cuando es insertar caracteres que no están en un teclado QWERTY tradicional. Los llamamos “dígrafos”. Puedes ver una lista de los dígrafos de Vim escribiendo:

:digraphs

NU ^@  10    SH ^A   1    SX ^B   2    EX ^C   3    ET ^D   4    EQ ^E   5
AK ^F   6    BL ^G   7    BS ^H   8    HT ^I   9    LF ^@  10    VT ^K  11
FF ^L  12    CR ^M  13    SO ^N  14    SI ^O  15    DL ^P  16    D1 ^Q  17
D2 ^R  18    D3 ^S  19    D4 ^T  20    NK ^U  21    SY ^V  22    EB ^W  23
CN ^X  24    EM ^Y  25    SB ^Z  26    EC ^[  27    FS ^\  28    GS ^]  29
RS ^^  30    US ^_  31    SP     32    Nb #   35    DO $   36    At @   64

Ahora, puedes insertar cualquiera de los caracteres en la columna derecha escribiendo CTRL-kseguido de las dos letras en la columna izquierda.

Por ejemplo, en mi computadora, para ingresar el signo de libra esterlina, puedo escribir esto cuando estoy en modo de inserción:

CTRL-k Pd

£

Código fuente


Si está codificando, hay varias cosas diferentes que lo ayudarán a interactuar con su código.

Una de las más básicas es el resaltado de sintaxis. Puedes activarlo escribiendo:

:syntax on

Esto debería configurar el resaltado de sintaxis para su archivo según la extensión detectada. Si desea cambiar el idioma del resaltado, puede hacerlo configurando el idioma con:

:set filetype=[language]

Si desea utilizar una utilidad del sistema para modificar algunas líneas de su archivo, puede llamarla usando el !comando en modo normal.

Este comando acepta un movimiento y luego lo envía al comando que le sigue.

![motion] filter

Por ejemplo, para ordenar las líneas desde la posición actual hasta el final del archivo, puede escribir:

!G sort

Sort es un comando de Linux que ordena la entrada, alfabéticamente de forma predeterminada.

Si queremos insertar la salida de un comando en el archivo, navegue hasta una línea en blanco donde desee la salida. Escriba:

!!command

Esto colocará la salida del comando especificado en el documento.

Si queremos ver el resultado de un comando, pero no deseamos insertarlo en el documento, también podemos utilizar la versión en modo comando (:), que sería:

:!command

Esto le mostrará los resultados del comando, pero regresará a su documento sin modificaciones cuando termine.

Reducir la repetición


A menudo, al editar o crear cualquier tipo de archivo, te encontrarás repitiendo muchas operaciones iguales o similares. Por suerte, vim ofrece algunas maneras de guardar grupos de comandos en macros.

Para comenzar a grabar una macro, puede escribir qseguido de una letra para hacer referencia a la macro.

qa    # will save macro "a"

Cualquier comando que escriba se grabará como parte de la macro. Para finalizar la macro, puede qvolver a escribir.

Entonces si escribimos:

qa0c3wDELETED<esc>q

Esto iniciaría una macro (guardada como “a”), iría al principio de la línea y reemplazaría las siguientes tres palabras con la palabra “DELETED”. Luego, saldría del modo de inserción y finalizaría la macro.

Para reproducir esta macro, comenzando en la posición actual del cursor, utilice el @carácter seguido de la referencia de la macro:

@a

Esto reproducirá los comandos macro comenzando en la posición actual.

Si queremos crear una macro que finalice en modo de inserción, debemos finalizarla de otra manera (al escribir “q”, simplemente se insertará una “q”). Podemos ejecutar un comando en modo normal en modo de inserción precediéndolo con “< CTRL-O.

Por lo tanto, si queremos cambiar el contenido de los primeros paréntesis de esta línea, podríamos tener una macro que diga:

qi0f(lct)<CTRL-O>q

Esto crea una macro “i”. La macro se desplaza al principio de la línea actual. Encuentra el paréntesis de apertura y se desplaza un carácter a la derecha (para moverse dentro del paréntesis). Después, cambia todo hasta el paréntesis de cierre. Con vim en modo de inserción esperando el texto de reemplazo, pulsamos CTRL-Oseguido de qpara finalizar la macro, quedando en modo de inserción listos para reemplazar el texto.

Conclusión


Ahora deberías tener una idea de algunas maneras más complejas en que vim puede ayudarte. Aunque esto pueda parecer mucho, es solo el comienzo.

Hay muchas funciones que no hemos mencionado, y no es necesario que las conozcas todas. Aprenderás lo importante según cómo uses vim. Cuanto más practiques y lo uses a diario, más natural te resultará y más potente será.

Stephen Dove
Comments

April 27, 2025

Dominando grep con expresiones regulares: Guía para una búsqueda de texto eficiente

Introducción

Este grepcomando es uno de los más útiles en un entorno de terminal Linux. Su nombre grepsignifica “impresión de expresión regular global”. Esto significa que se puede usar greppara comprobar si la entrada que recibe coincide con un patrón específico. Este programa, aparentemente trivial, es extremadamente potente; su capacidad para ordenar la entrada según reglas complejas lo convierte en un enlace popular en muchas cadenas de comandos.

En este tutorial, explorará las grepopciones del comando y luego profundizará en el uso de expresiones regulares para realizar búsquedas más avanzadas.

Prerrequisitos

Para seguir esta guía, necesitará acceder a un ordenador con sistema operativo Linux. Puede ser un servidor privado virtual al que se haya conectado por SSH o su equipo local. Tenga en cuenta que este tutorial se validó con un servidor Linux con Ubuntu 20.04, pero los ejemplos proporcionados deberían funcionar en cualquier ordenador con cualquier versión de Linux.

Si planea usar un servidor remoto para seguir esta guía, le recomendamos que primero complete nuestra guía de configuración inicial del servidor . Esto le permitirá configurar un entorno de servidor seguro, que incluye un usuario no root con sudoprivilegios y un firewall configurado con UFW, que puede usar para mejorar sus habilidades con Linux.

Uso básico

En este tutorial, utilizarás grepla Licencia Pública General GNU versión 3 para buscar varias palabras y frases.

Si usas Ubuntu, puedes encontrar el archivo en la /usr/share/common-licensescarpeta. Cópialo a tu directorio personal:

cp /usr/share/common-licenses/GPL-3 .

Si estás en otro sistema, usa el curlcomando para descargar una copia:

curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

También usarás el archivo de licencia BSD en este tutorial. En Linux, puedes copiarlo a tu directorio personal con el siguiente comando:

cp /usr/share/common-licenses/BSD .

Si está en otro sistema, cree el archivo con el siguiente comando:

cat << 'EOF' > BSD
Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
EOF

Ahora que tienes los archivos, puedes empezar a trabajar con grep.

En su forma más básica, se usa greppara buscar patrones literales dentro de un archivo de texto. Esto significa que, si se pasa grepuna palabra a buscar, se imprimirán todas las líneas del archivo que la contengan.

Ejecute el siguiente comando para grepbuscar cada línea que contenga la palabra GNU:

grep "GNU" GPL-3

El primer argumento, GNU, es el patrón que estás buscando, mientras que el segundo argumento, GPL-3, es el archivo de entrada que deseas buscar.

La salida resultante será cada línea que contenga el texto del patrón:

Output                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
  Developers that use the GNU GPL protect your rights with two steps:
  "This License" refers to version 3 of the GNU General Public License.
  13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...

En algunos sistemas, el patrón que buscó aparecerá resaltado en la salida.

Opciones comunes

De forma predeterminada, grepbuscará el patrón exacto especificado en el archivo de entrada y devolverá las líneas que encuentre. Sin embargo, puede hacer que este comportamiento sea más útil añadiendo indicadores opcionales a grep.

Si desea grepignorar las mayúsculas y minúsculas de su parámetro de búsqueda y buscar variaciones en mayúsculas y minúsculas, puede especificar la opción -io .--ignore-case

Busque cada instancia de la palabra license(con mayúsculas, minúsculas o mixtas) en el mismo archivo que antes con el siguiente comando:

grep -i "license" GPL-3

Los resultados contienen: LICENSE, license, y License:

Output                    GNU GENERAL PUBLIC LICENSE
 of this license document, but changing it is not allowed.
  The GNU General Public License is a free, copyleft license for
  The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
  "This License" refers to version 3 of the GNU General Public License.
  "The Program" refers to any copyrightable work licensed under this
...
...

Si hubiera habido una instancia con LiCeNsE, ésta también se habría devuelto.

Si desea encontrar todas las líneas que no contienen un patrón especificado, puede utilizar la opción -vo --invert-match.

Busque cada línea que no contenga la palabra theen la licencia BSD con el siguiente comando:

grep -v "the" BSD

Recibirás este resultado:

OutputAll rights reserved.

Redistribution and use in source and binary forms, with or without
are met:
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

Como no especificó la opción “ignorar mayúsculas y minúsculas”, los dos últimos elementos se devolvieron como si no tuvieran la palabra the.

Suele ser útil conocer el número de línea donde se producen las coincidencias. Puede hacerlo usando la opción -n“o” --line-number. Repita el ejemplo anterior con esta opción añadida:

grep -vn "the" BSD

Esto devolverá el siguiente texto:

Output2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13:   may be used to endorse or promote products derived from this software
14:   without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

Ahora puedes referenciar el número de línea si quieres modificar todas las líneas que no contengan “<sub>” the. Esto resulta especialmente útil al trabajar con código fuente.

Expresiones regulares

En la introducción, aprendiste que grepsignifica “impresión de expresión regular global”. Una “expresión regular” es una cadena de texto que describe un patrón de búsqueda específico.

Distintas aplicaciones y lenguajes de programación implementan expresiones regulares de forma ligeramente distinta. En este tutorial, solo explorarás una pequeña parte de cómo grepse describen sus patrones.

Coincidencias literales

En los ejemplos anteriores de este tutorial, al buscar las palabras GNUy the, en realidad, buscaba expresiones regulares básicas que coincidieran con la cadena exacta de caracteres GNUy the. Los patrones que especifican con precisión los caracteres que se deben buscar se denominan “literales” porque coinciden con el patrón literalmente, carácter por carácter.

Es útil pensar en ellos como si coincidieran con una cadena de caracteres en lugar de una palabra. Esta distinción será más importante a medida que aprendas patrones más complejos.

Todos los caracteres alfabéticos y numéricos (así como algunos otros caracteres) coinciden literalmente a menos que sean modificados por otros mecanismos de expresión.

Partidos de ancla

Los anclajes son caracteres especiales que especifican en qué parte de la línea debe producirse una coincidencia para que sea válida.

Por ejemplo, al usar anclas, puede especificar que solo desea conocer las líneas que coinciden GNUal principio de la línea. Para ello, puede usar el ^ancla antes de la cadena literal.

Ejecute el siguiente comando para buscar en el GPL-3archivo y encontrar líneas donde GNUaparece al principio de una línea:

grep "^GNU" GPL-3

Este comando devolverá las siguientes dos líneas:

OutputGNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published

De manera similar, se utiliza el $ancla al final de un patrón para indicar que la coincidencia solo será válida si ocurre al final de una línea.

Este comando coincidirá con cada línea que termine con la palabra anden el GPL-3archivo:

grep "and$" GPL-3

Recibirás este resultado:

Outputthat there is no warranty for this free software.  For both users' and
  The precise terms and conditions for copying, distribution and
  License.  Each licensee is addressed as "you".  "Licensees" and
receive it, in any medium, provided that you conspicuously and
    alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and

Coincidencia de cualquier personaje

El carácter de punto (.) se utiliza en expresiones regulares para indicar que cualquier carácter individual puede existir en la ubicación especificada.

Por ejemplo, para hacer coincidir cualquier cosa en el GPL-3archivo que tenga dos caracteres y luego la cadena cept, utilizaría el siguiente patrón:

grep "..cept" GPL-3

Este comando devuelve el siguiente resultado:

Outputuse, which is precisely where it is most unacceptable.  Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
  You may not propagate or modify a covered work except as expressly
  9. Acceptance Not Required for Having Copies.
...
...

Esta salida contiene instancias de ” accepty except” y variaciones de ambas palabras. El patrón también habría coincidido z2ceptsi se hubiera encontrado.

Expresiones entre paréntesis

Al colocar un grupo de caracteres entre corchetes ( \[y \]), puede especificar que el carácter en esa posición puede ser cualquier carácter que se encuentre dentro del grupo de corchetes.

Por ejemplo, para encontrar las líneas que contienen tooo two, deberá especificar esas variaciones sucintamente utilizando el siguiente patrón:

grep "t[wo]o" GPL-3

La salida muestra que ambas variaciones existen en el archivo:

Outputyour programs, too.
freedoms that you received.  You must make sure that they, too, receive
  Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
    Corresponding Source from a network server at no charge.
...
...

La notación entre corchetes ofrece opciones interesantes. Puedes hacer que el patrón coincida con cualquier carácter excepto los dentro de un corchete, comenzando la lista de caracteres dentro de los corchetes con un ^carácter.

Este ejemplo es como el patrón .ode, pero no coincidirá con el patrón code:

grep "[^c]ode" GPL-3

Aquí está el resultado que recibirás:

Output  1. Source Code.
    model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:

Observe que en la segunda línea devuelta, se encuentra la palabra code. Esto no se debe a un error de la expresión regular ni de grep. Más bien, esta línea se devolvió porque anteriormente se encontró el patrón mode, presente en la palabra model. La línea se devolvió porque existía una instancia que coincidía con el patrón.

Otra característica útil de los corchetes es que puedes especificar un rango de caracteres en lugar de escribir individualmente cada carácter disponible.

Esto significa que si desea encontrar cada línea que comience con una letra mayúscula, puede utilizar el siguiente patrón:

grep "^[A-Z]" GPL-3

Aquí está el resultado que devuelve esta expresión:

OutputGNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License.  Each licensee is addressed as "you".  "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
...

Debido a algunos problemas de clasificación heredados, a menudo es más preciso utilizar clases de caracteres POSIX en lugar de rangos de caracteres como los que acaba de utilizar.

Analizar cada clase de carácter POSIX quedaría fuera del alcance de esta guía, pero un ejemplo que lograría el mismo procedimiento que el ejemplo anterior utiliza la \[:upper:\]clase de carácter dentro de un selector de corchetes:

grep "^[[:upper:]]" GPL-3

La salida será la misma que antes.

Repetir el patrón cero o más veces

Por último, uno de los metacaracteres más utilizados es el asterisco, o *, que significa “repetir el carácter o expresión anterior cero o más veces”.

Para encontrar cada línea en el GPL-3archivo que contiene un paréntesis de apertura y cierre, con solo letras y espacios simples en el medio, use la siguiente expresión:

grep "([A-Za-z ]*)" GPL-3

Obtendrá el siguiente resultado:

Output Copyright (C) 2007 Free Software Foundation, Inc.
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
    (including a physical distribution medium), accompanied by the
    (including a physical distribution medium), accompanied by a
    place (gratis or for a charge), and offer equivalent access to the
...
...

Hasta ahora has utilizado puntos, asteriscos y otros caracteres en tus expresiones, pero a veces necesitas buscar esos caracteres específicamente.

Escapar de metacaracteres

En ocasiones, necesitará buscar un punto literal o un corchete de apertura literal, especialmente al trabajar con código fuente o archivos de configuración. Dado que estos caracteres tienen un significado especial en las expresiones regulares, deberá “escaparlos” para indicar grepque no desea usar su significado especial en este caso.

Para escapar caracteres, utilice el carácter de barra invertida ( \) delante del carácter que normalmente tendría un significado especial.

Por ejemplo, para encontrar cualquier línea que comience con una letra mayúscula y termine con un punto, utilice la siguiente expresión que escapa del punto final para que represente un punto literal en lugar del significado habitual de “cualquier carácter”:

grep "^[A-Z].*\.$" GPL-3

Este es el resultado que verás:

OutputSource.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.

Ahora veamos otras opciones de expresiones regulares.

Expresiones regulares extendidas

El grepcomando admite un lenguaje de expresiones regulares más extenso al usar la -Ebandera o al llamar al egrepcomando en lugar de grep.

Estas opciones amplían las posibilidades de las expresiones regulares extendidas. Estas expresiones regulares incluyen todos los metacaracteres básicos, además de metacaracteres adicionales para expresar coincidencias más complejas.

Agrupamiento

Una de las capacidades más útiles que ofrecen las expresiones regulares extendidas es la capacidad de agrupar expresiones para manipularlas o referenciarlas como una unidad.

Para agrupar expresiones, enciérrelas entre paréntesis. Si desea usar paréntesis sin usar expresiones regulares extendidas, puede escaparlas con la barra invertida para habilitar esta función. Esto significa que las siguientes tres expresiones son funcionalmente equivalentes:

grep "\(grouping\)" file.txt
grep -E "(grouping)" file.txt
egrep "(grouping)" file.txt

Alternancia

De manera similar a cómo las expresiones entre corchetes pueden especificar diferentes opciones posibles para coincidencias de un solo carácter, la alternancia le permite especificar coincidencias alternativas para cadenas o conjuntos de expresiones.

Para indicar alternancia, utilice el carácter de barra vertical |. Estos se utilizan a menudo en la agrupación entre paréntesis para especificar que una de dos o más posibilidades debe considerarse una coincidencia.

GPLLo siguiente lo encontrará General Public Licenseen el texto:

grep -E "(GPL|General Public License)" GPL-3

El resultado se ve así:

Output  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
  Developers that use the GNU GPL protect your rights with two steps:
  For the developers' and authors' protection, the GPL clearly explains
authors' sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
...

La alternancia puede seleccionar entre más de dos opciones agregando opciones adicionales dentro del grupo de selección separadas por |caracteres de barra vertical ( ).

Cuantificadores

Al igual que el *metacarácter que coincidió con el carácter o conjunto de caracteres anterior cero o más veces, hay otros metacaracteres disponibles en expresiones regulares extendidas que especifican la cantidad de ocurrencias.

Para que un carácter coincida cero o una vez, puedes usar el ?carácter. Esto hace que los caracteres o conjuntos de caracteres anteriores sean, en esencia, opcionales.

Los siguientes partidos copyrighty rightponiendo copyen un grupo opcional:

grep -E "(copy)?right" GPL-3

Recibirás este resultado:

Output Copyright (C) 2007 Free Software Foundation, Inc.
  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
know their rights.
  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
  "Copyright" also means copyright-like laws that apply to other kinds of
...

El +carácter coincide con una expresión una o más veces. Es similar al *metacarácter, pero con el +carácter, la expresión debe coincidir al menos una vez.

La siguiente expresión coincide con la cadena freemás uno o más caracteres que no sean espacios en blanco:

grep -E "free[^[:space:]]+" GPL-3

Verás este resultado:

Output  The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
  When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for
you modify it: responsibilities to respect the freedom of others.
freedomss that you received.  You must make sure that they, too, receive
protecting users' freedom to change the software.  The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.

Especificación de la repetición de coincidencias

Para especificar el número de veces que se repite una coincidencia, utilice las llaves ( {y }). Estas llaves permiten especificar un número exacto, un rango o un límite superior o inferior para la cantidad de veces que una expresión puede coincidir.

Utilice la siguiente expresión para encontrar todas las líneas del GPL-3archivo que contienen vocales triples:

grep -E "[AEIOUaeiou]{3}" GPL-3

Cada línea devuelta tiene una palabra con tres vocales:

Outputchanged, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this

Para encontrar cualquier palabra que tenga entre 16 y 20 caracteres, utilice la siguiente expresión:

grep -E "[[:alpha:]]{16,20}" GPL-3

Aquí está el resultado de este comando:

Output    certain responsibilities if you distribute copies of the software, or if
    you modify it: responsibilities to respect the freedom of others.
        c) Prohibiting misrepresentation of the origin of that material, or

Sólo se muestran las líneas que contienen palabras dentro de esa longitud.

Casos de uso práctico

1. Validación de campos CSV

Para validar campos CSV, puede usar grepexpresiones regulares para buscar patrones o formatos específicos. Por ejemplo, para comprobar si todas las líneas de un archivo CSV tienen exactamente 5 campos separados por comas, puede usar el siguiente comando:

grep -E "^[^,]+,[^,]+,[^,]+,[^,]+,[^,]+$" yourfile.csv

Este comando imprimirá solo las líneas que coincidan con el patrón especificado, indicando campos CSV válidos.

2. Filtrar registros por nivel de error (por ejemplo, grep “ERROR” logs.txt)

Filtrar registros por nivel de error es un uso común de grep. Para filtrar registros por líneas que contengan la palabra “ERROR”, puede usar el siguiente comando:

grep "ERROR" logs.txt

Este comando imprimirá todas las líneas logs.txtque contengan la palabra “ERROR”, lo que le permitirá centrarse en los mensajes de error.

3. Búsqueda de funciones específicas en el código fuente

Al buscar en el código fuente, grepse puede usar para encontrar funciones o patrones específicos. Por ejemplo, para encontrar todas las ocurrencias de una función nombrada calculateTotalen un directorio de archivos de código fuente, se puede usar el siguiente comando:

grep -r "calculateTotal" /path/to/source/code/directory

Este comando buscará recursivamente todos los archivos en el directorio especificado e imprimirá las líneas que contienen el nombre de la función.

4. Coincidencia de URL o direcciones de correo electrónico en el texto

Se pueden usar expresiones regulares para buscar coincidencias entre URL o direcciones de correo electrónico en texto. Por ejemplo, para encontrar todas las líneas de un archivo que contienen una URL, puede usar el siguiente comando:

grep -E "https?://[^ ]+" yourfile.txt

Este comando imprimirá todas las líneas que contengan una URL que comience con “http://” o “https://”.

5. Preprocesamiento de PNL: filtrado de líneas con palabras vacías

Las palabras vacías son palabras comunes como “el”, “y”, etc., que no tienen mucho significado en una oración. Para filtrar líneas que contienen palabras vacías, puede usar grepuna lista de palabras vacías. Por ejemplo, para filtrar líneas que contienen las palabras vacías “el”, “y” o “un”, puede usar el siguiente comando:

grep -vE "the|and|a" yourfile.txt

Este comando imprimirá todas las líneas que no contengan ninguna de las palabras vacías especificadas.

6. Detección de entradas casi duplicadas o errores ortográficos

Las expresiones regulares permiten detectar entradas casi duplicadas o errores ortográficos mediante la búsqueda de patrones similares. Por ejemplo, para encontrar líneas que contengan palabras con una sola diferencia de carácter, se puede usar el siguiente comando:

grep -E "(\w)\1" yourfile.txt

Este comando imprimirá todas las líneas que contengan palabras con un solo carácter repetido, lo que indica posibles duplicados o errores ortográficos.

7. Patrones de expresiones regulares para entidades con nombre o frases comunes

Las expresiones regulares permiten encontrar coincidencias entre entidades con nombre o frases comunes en el texto. Por ejemplo, para encontrar todas las líneas que contienen una frase específica como “reconocimiento de entidad con nombre”, se puede usar el siguiente comando:

grep -E "named entity recognition" yourfile.txt

Este comando imprimirá todas las líneas que contengan la frase especificada, lo que le permitirá centrarse en la información relevante.

Errores comunes y depuración

1. Usar operadores de expresiones regulares como *, + o ? sin escaparlos

Al usar operadores de expresiones regulares como *, +, o ?, es fundamental escaparlos correctamente para evitar coincidencias inesperadas. Por ejemplo, si desea que coincida con el carácter literal *, debe escaparlo con una barra invertida ( \*). De igual forma, para que coincida con los caracteres literales +o ?, escápelos con una barra invertida ( \+o \?).

Ejemplo de comando para hacer coincidir un *carácter literal:

grep -E "a\*" yourfile.txt

2. Coincidencia de líneas vacías o líneas con solo espacios en blanco

Para hacer coincidir líneas vacías o líneas con solo espacios en blanco, puede utilizar el siguiente patrón de expresión regular:

grep -E "^\s*$" yourfile.txt

Este patrón coincide con líneas que comienzan ( ^) y terminan ( $) con cualquier carácter de espacio en blanco ( \s*).

3. Tabulaciones (\t) y retornos de carro (\r)

Para hacer coincidir tabulaciones ( \t) o retornos de carro ( \r) en su texto, puede utilizar los siguientes comandos:

# Match lines containing tabs
grep -E "\t" yourfile.txt

# Match lines containing carriage returns
grep -E "\r" yourfile.txt

Tenga en cuenta que en algunos casos, es posible que necesite usar la -Eopción para habilitar patrones de expresiones regulares extendidos, que le permiten usar funciones de expresiones regulares más avanzadas.

Diferencias entre grep, egrep y fgrep

DominioDescripciónCaracterísticasCasos de usoComando de muestra
grepCoincidencia de patrones básicosAdmite expresiones regulares básicasCoincidencia de patrones generalesgrep "pattern" file.txt
egrepCoincidencia de patrones extendidaAdmite expresiones regulares extendidasCoincidencia de patrones complejosegrep "pattern" file.txt
fgrepCoincidencia de patrones fijosSin soporte para expresiones regularesCoincidencia de cadenas fijasfgrep "pattern" file.txt

<$>[noe] Nota: La principal diferencia entre estos comandos es el tipo de coincidencia de patrones que admiten. grepAdmite expresiones regulares básicas, egrepadmite expresiones regulares extendidas y fgrepno admite expresiones regulares en absoluto. <$>

Manejo de patrones multilínea

grepNo es adecuado para gestionar patrones multilínea debido a su naturaleza lineal. Sin embargo, existen herramientas alternativas que pueden gestionar eficazmente estos patrones. awkSon perldos opciones populares para buscar patrones que abarcan varias líneas.

awkEs una potente herramienta de procesamiento de texto que permite encontrar patrones en varias líneas. Permite definir un patrón y realizar acciones en las líneas coincidentes. Por ejemplo, para encontrar líneas que contengan un patrón en varias líneas, se puede usar el siguiente comando:

awk '/pattern/ {print $0}' yourfile.txt

Este comando imprimirá todas las líneas que coincidan con el patrón especificado. Tenga en cuenta que awktambién puede usarse para realizar operaciones más complejas en las líneas coincidentes, como imprimir todo el bloque de texto que coincide con el patrón.

perlEs otra herramienta potente que permite gestionar patrones multilínea. Ofrece una forma más flexible y expresiva de encontrar coincidencias de patrones mediante su motor de expresiones regulares integrado. Por ejemplo, puede usar el siguiente comando para buscar líneas que contengan un patrón en varias líneas:

perl -0777 -ne 'print if /pattern/s' yourfile.txt

Este comando indica perlque se lea el archivo en modo “slurp” ( -0777), lo que permite leerlo completo en memoria de una sola vez. La -neopción especifica que el script debe ejecutarse para cada línea del archivo. La print if /pattern/sinstrucción busca la coincidencia del patrón en varias líneas (gracias al smodificador) e imprime el bloque de texto completo que coincide.

Ambos ofrecen funciones más avanzadas y flexibilidad cuando awkse trata de manejar patrones multilínea, lo que los convierte en alternativas ideales para tales tareas.perlgrep

Preguntas frecuentes

1. ¿Cuál es la diferencia entre grep y egrep?

grepy egrepambos se utilizan para la coincidencia de patrones, pero difieren en el tipo de patrones que admiten. grepadmite expresiones regulares básicas, mientras que egrepadmite expresiones regulares extendidas, que permiten una coincidencia de patrones más avanzada.

2. ¿Puedo usar grep para buscar en varios archivos?

Sí, puedes grepbuscar en varios archivos especificando varios nombres de archivo o usando comodines. Por ejemplo:

grep "pattern" file1.txt file2.txt

o

grep "pattern" *.txt

3. ¿Cómo puedo buscar líneas que no coinciden con un patrón?

Para buscar líneas que no coincidan con un patrón, use la -vopción. Por ejemplo:

grep -v "pattern" yourfile.txt

Esto imprimirá todas las líneas que no contengan el patrón especificado.

4. ¿Cómo incluyo números de línea en la salida de grep?

Para incluir números de línea en grepla salida, utilice la -nopción. Por ejemplo:

grep -n "pattern" yourfile.txt

Esto imprimirá los números de línea junto con las líneas que coincidan con el patrón especificado.

5. ¿Por qué mi expresión regular grep no funciona como se esperaba?

Puede haber varias razones por las que tu grepexpresión regular no funciona como se espera. Aquí tienes algunos problemas comunes que debes revisar:

  • Asegúrese de estar utilizando la sintaxis correcta para su patrón de expresión regular.
  • Asegúrese de estar utilizando las opciones correctas para su grepcomando (por ejemplo, -Epara expresiones regulares extendidas).
  • Comprueba si tu patrón contiene caracteres especiales que es necesario escapar.
  • Verifique que su patrón esté citado correctamente para evitar la interpretación del shell.

6. ¿Cómo puedo buscar un patrón que incluya espacios en blanco o caracteres especiales?

Para buscar un patrón que incluya espacios o caracteres especiales, debe escaparlos correctamente en su patrón de expresión regular. Por ejemplo, para buscar un patrón que incluya espacios, utilice el siguiente comando:

grep "pattern\ with\ whitespace" yourfile.txt

De forma similar, para buscar un patrón que incluya caracteres especiales, escápelos con una barra invertida ( \). Por ejemplo:

grep "pattern\ with\ special\ characters" yourfile.txt

Conclusión

grepEs una herramienta poderosa para encontrar patrones dentro de archivos o en la jerarquía del sistema de archivos. Dominar sus opciones y sintaxis mejorará enormemente su capacidad para trabajar con datos de texto.

Las expresiones regulares son un concepto fundamental en informática, y comprenderlas abre un amplio abanico de posibilidades. Desde la búsqueda y el reemplazo avanzados de texto en editores de texto hasta la validación de datos en lenguajes de programación, las expresiones regulares son una habilidad esencial.

Para mejorar aún más tus habilidades, te recomendamos consultar los siguientes tutoriales:

  • El comando Grep en Linux/Unix
  • Introducción a las expresiones regulares
  • Comandos de Linux
  • Las mejores herramientas de recuperación de datos de Linux

Al explorar estos tutoriales, obtendrá una comprensión más profunda de grep, expresiones regulares y otras herramientas esenciales de Linux, lo que le permitirá abordar una amplia gama de tareas con confianza.

Stephen Dove
Comments

April 27, 2025

Cómo usar SFTP para transferir archivos con un servidor remoto de manera segura

Introducción

FTP, o “File Transfer Protocol” (Protocolo de transferencia de archivos), era un método popular sin cifrar para transferir archivos entre dos sistemas remotos.

SFTP, que significa Protocolo de transferencia de archivos SSH o Protocolo de transferencia segura de archivos, es un protocolo independiente empaquetado con SSH que funciona de forma similar pero a través de una conexión segura. La ventaja es la capacidad de aprovechar una conexión segura para transferir archivos y recorrer el sistema de archivos en los sistemas local y remoto.

En casi todos los casos, es preferible usar SFTP, en vez de FTP, debido a sus características de seguridad subyacentes y a su capacidad para aprovechar una conexión SSH. FTP es un protocolo no seguro que solo debería utilizarse en casos limitados o en redes de confianza.

Aunque SFTP está integrado en muchas herramientas gráficas, esta guía mostrará cómo utilizarlo en su interfaz de línea de comandos interactiva.

Cómo conectarse con SFTP

De forma predeterminada, SFTP utiliza el protocolo SSH para autenticarse y establecer una conexión segura. Por eso, están disponibles los mismos métodos de autenticación que en SSH.

Aunque las contraseñas son fáciles de usar y se configuran de forma predeterminada, le recomendamos crear claves SSH y transferir su clave pública a cualquier sistema al que necesite acceder. Eso es mucho más seguro y puede ahorrarle tiempo a largo plazo.

Consulte esta guía para configurar claves SSH para acceder a su servidor si aún no lo hizo.

Si puede conectarse al equipo usando SSH, habrá completado todos los requisitos necesarios para usar SFTP para administrar archivos. Pruebe el acceso SSH con el siguiente comando:

ssh sammy@your_server_ip_or_remote_hostname

Si esto funciona, salga de nuevo escribiendo:

exit

Ahora, podemos establecer una sesión SFTP ejecutando el siguiente comando:

sftp sammy@your_server_ip_or_remote_hostname

Conectará el sistema remoto, y la entrada de su línea de comandos cambiará a una instrucción SFTP.

Si está trabajando en un puerto SSH personalizado (no el puerto 22 predeterminado), puede iniciar una sesión SFTP de la siguiente manera:

sftp -oPort=custom_port sammy@your_server_ip_or_remote_hostname

Eso lo conectará al sistema remoto mediante el puerto especificado.

Cómo obtener ayuda en SFTP

El comando más útil que debe conocer primero es el comando help. Este comando le da acceso a un resumen de la ayuda en SFTP. Puede invocarlo escribiendo cualquiera de estos en la instrucción:

help

o

?

Eso mostrará una lista de los comandos disponibles:

OutputAvailable commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
chgrp grp path                     Change group of file 'path' to 'grp'
chmod mode path                    Change permissions of file 'path' to 'mode'
chown own path                     Change owner of file 'path' to 'own'
df [-hi] [path]                    Display statistics for current directory or
                                   filesystem containing 'path'
exit                               Quit sftp
get [-Ppr] remote [local]          Download file
help                               Display this help text
lcd path                           Change local directory to 'path'
. . .

En las siguientes secciones, exploraremos algunos de los comandos que verá.

Cómo navegar con SFTP

Podemos navegar a través de la jerarquía de archivos del sistema remoto usando varios comandos que funcionan de forma similar a sus contrapartes de shell.

Primero, orientémonos averiguando en qué directorio estamos actualmente en el sistema remoto. Al igual que en una sesión típica de shell, podemos escribir lo siguiente para obtener el directorio actual:

pwd

OutputRemote working directory: /home/demouser

Podemos ver el contenido del directorio actual del sistema remoto con otro comando familiar:

ls

OutputSummary.txt     info.html       temp.txt        testDirectory

Tenga en cuenta que los comandos en la interfaz SFTP no son los comandos de shell normales y no cuentan con la misma cantidad de funciones, pero implementan algunos de los indicadores opcionales más importantes:

ls -la

Outputdrwxr-xr-x    5 demouser   demouser       4096 Aug 13 15:11 .
drwxr-xr-x    3 root     root         4096 Aug 13 15:02 ..
-rw-------    1 demouser   demouser          5 Aug 13 15:04 .bash_history
-rw-r--r--    1 demouser   demouser        220 Aug 13 15:02 .bash_logout
-rw-r--r--    1 demouser   demouser       3486 Aug 13 15:02 .bashrc
drwx------    2 demouser   demouser       4096 Aug 13 15:04 .cache
-rw-r--r--    1 demouser   demouser        675 Aug 13 15:02 .profile
. . .

Para llegar a otro directorio, podemos ejecutar este comando:

cd testDirectory

Ahora, podemos recorrer el sistema de archivos remotos, pero ¿qué pasa si necesitamos acceder a nuestro sistema de archivos local? Podemos dirigir los comandos al sistema de archivos locales precediéndolos con una l que hace referencia a “local”.

Todos los comandos examinados hasta ahora tienen equivalentes locales. Podemos imprimir el directorio local de trabajo:

lpwd

OutputLocal working directory: /Users/demouser

Podemos enumerar el contenido del directorio actual en el equipo local:

lls

OutputDesktop			local.txt		test.html
Documents		analysis.rtf		zebra.html

También podemos cambiar el directorio con el que deseamos interactuar en el sistema local:

lcd Desktop

Cómo transferir archivos con SFTP

Navegar por los sistemas de archivos locales y remotos es muy poco útil si no se puede transferir archivos entre ambos.

Transferencia de archivos remotos al sistema local

Si queremos descargar archivos de nuestro host remoto, podemos hacerlo ejecutando el siguiente comando:

get remoteFile

OutputFetching /home/demouser/remoteFile to remoteFile
/home/demouser/remoteFile                       100%   37KB  36.8KB/s   00:01

Como puede ver, de forma predeterminada, el comando get descarga un archivo remoto a un archivo con el mismo nombre en el sistema de archivos locales.

Podemos copiar el archivo remoto a un nombre diferente especificando el nombre después:

get remoteFile localFile

El comando get también toma algunos indicadores de opción. Por ejemplo, podemos copiar un directorio y todo su contenido especificando la opción recursiva:

get -r someDirectory

Podemos indicarle a SFTP que mantenga los permisos y los tiempos de acceso adecuados utilizando el indicador -P o -p:

get -Pr someDirectory

Transferencia de archivos locales al sistema remoto

Transferir archivos al sistema remoto es tan fácil como utilizar el comando correctamente llamado “put”:

put localFile

OutputUploading localFile to /home/demouser/localFile
localFile                                     100% 7607     7.4KB/s   00:00

Los mismos indicadores que funcionan con get se aplican a put. Para copiar un directorio local completo, puede ejecutar:

put -r localDirectory

Nota: Actualmente, hay un error en las versiones de OpenSSH incluidas en las versiones actuales de Ubuntu (al menos de la versión 14.04 a la 15.10) que impide que el comando anterior funcione correctamente. Cuando se ejecuta el comando anterior para transferir contenido a un servidor utilizando la versión con errores de OpenSSH, se producirá el siguiente error: Couldn't canonicalise: No such file or directory (No se pudo canonizar: no existe tal archivo o directorio).

Para resolver este problema, primero cree el directorio de destino en el extremo remoto escribiendo mkdir localDirectory. Luego, el comando anterior debería completarse sin errores.

Una herramienta familiar que es útil para descargar y cargar archivos es el comando df, que funciona de forma similar a la versión de la línea de comandos. Al utilizarla, puede verificar que tiene suficiente espacio para completar las transferencias que le interesan:

df -h

Output    Size     Used    Avail   (root)    %Capacity
  19.9GB   1016MB   17.9GB   18.9GB           4%

Tenga en cuenta que no hay ninguna variación local de este comando, pero podemos solucionarlo ejecutando ! como comando.

El comando ! nos lleva a un shell local, donde podemos ejecutar cualquier comando disponible en nuestro sistema local. Podemos verificar el uso del disco escribiendo lo siguiente:

!

y luego

df -h

OutputFilesystem      Size   Used  Avail Capacity  Mounted on
/dev/disk0s2   595Gi   52Gi  544Gi     9%    /
devfs          181Ki  181Ki    0Bi   100%    /dev
map -hosts       0Bi    0Bi    0Bi   100%    /net
map auto_home    0Bi    0Bi    0Bi   100%    /home

Cualquier otro comando local funcionará de la manera esperada. Para volver a su sesión SFTP, escriba lo siguiente:

exit

Ahora, debería ver el retorno de la instrucción de SFTP.

Manipulaciones de archivos simples con SFTP

SFTP le permite realizar el tipo de mantenimiento básico de archivos que es útil cuando se trabaja con jerarquías de archivos.

Por ejemplo, puede cambiar el propietario de un archivo en el sistema remoto con:

chown userID file

Observe cómo, a diferencia del comando chmod del sistema, el comando SFTP no acepta nombres de usuario, sino que utiliza UID. Lamentablemente, no hay una manera sencilla de saber el UID adecuado desde la interfaz SFTP.

Se puede realizar una solución alternativa más compleja con:

get /etc/passwd
!less passwd

Outputroot:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
. . .

Observe cómo en vez de utilizar el comando ! en sí, lo utilizamos como prefijo para un comando de shell local. Eso funciona para ejecutar cualquier comando disponible en nuestro equipo local y podría haberse utilizado anteriormente con el comando local df.

El UID se encuentra en la tercera columna del archivo, delimitado por caracteres de dos puntos.

De manera similar, podemos cambiar el propietario del grupo de un archivo con:

chgrp groupID file

De nuevo, no existe una forma sencilla de obtener una lista de los grupos del sistema remoto. Podemos solucionarlo con el siguiente comando:

get /etc/group
!less group

Outputroot:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
. . .

La tercera columna contiene el ID del grupo asociado con el nombre en la primera columna. Eso es lo que buscamos.

Por suerte, el comando chmod funciona correctamente en el sistema de archivos remotos:

chmod 777 publicFile

OutputChanging mode on /home/demouser/publicFile

No existe ningún comando para manipular permisos de archivo locales, pero puede quitar la máscara local para que todos los archivos que se copien al sistema local tengan los permisos adecuados.

Eso se puede lograr con el comando lumask:

lumask 022

OutputLocal umask: 022

Ahora, todos los archivos regulares descargados (siempre que no se utilice el indicador -p) tendrán 644 permisos.

SFTP permite crear directorios en sistemas locales y en sistemas remotos con lmkdir y mkdir, respectivamente. Estos funcionan de la manera prevista.

El resto de los comandos del archivo solo apuntan al sistema de archivos remotos:

ln
rm
rmdir

Estos comandos replican el comportamiento básico de las versiones del shell. Si necesita realizar estas acciones en el sistema de archivos local, recuerde que puede ingresar a un shell ejecutando este comando:

!

O ejecutar un comando único en el sistema local anteponiendo ! al comando de esta manera:

!chmod 644 somefile

Cuando termine con la sesión SFTP, utilice exit o bye para cerrar la conexión.

bye

Conclusión

Aunque SFTP es una herramienta simple, es muy útil para administrar servidores y transferir archivos entre ellos.

Por ejemplo, puede usar SFTP para permitir que determinados usuarios transfieran archivos sin acceso SSH. Para obtener más información sobre este proceso, consulte nuestro tutorial Cómo habilitar SFTP sin acceso de shell.

Si está acostumbrado a utilizar FTP o SCP para realizar sus transferencias, SFTP es una buena forma de aprovechar las ventajas de ambos. Si bien no es adecuado para todas las situaciones, es útil tenerlo en su repertorio por ser una herramienta flexible.

Stephen Dove
Comments

April 18, 2025

Cómo instalar Docker en Ubuntu: guía paso a paso

Introducción

Docker es una aplicación que simplifica la gestión de procesos de aplicaciones en contenedores . Los contenedores permiten ejecutar aplicaciones en procesos con recursos aislados. Son similares a las máquinas virtuales, pero son más portátiles, consumen menos recursos y dependen más del sistema operativo host.

Para obtener una introducción detallada a los diferentes componentes de un contenedor Docker, consulte El ecosistema de Docker: una introducción a los componentes comunes .

En este tutorial, instalarás y usarás Docker Community Edition (CE) en Ubuntu. Instalarás Docker, trabajarás con contenedores e imágenes, y subirás una imagen a un repositorio de Docker. Además, aprenderás a iniciar, detener y eliminar contenedores, así como a confirmar los cambios de un contenedor en una nueva imagen de Docker. Este tutorial también explica cómo instalar Docker con compatibilidad con GPU, errores comunes y cómo solucionarlos, y las mejores prácticas de seguridad.

Implemente directamente desde GitHub en minutos.

Prerrequisitos

Para seguir este tutorial, necesitarás lo siguiente:

  • Un servidor Ubuntu configurado siguiendo la guía de configuración inicial del servidor Ubuntu , incluido un usuario sudono root y un firewall.
  • Una cuenta en Docker Hub si desea crear sus propias imágenes y enviarlas a Docker Hub, como se muestra en los pasos 7 y 8.

Paso 1: Instalación de Docker

El paquete de instalación de Docker disponible en el repositorio oficial de Ubuntu podría no ser la última versión. Para asegurarnos de obtener la última versión, instalaremos Docker desde el repositorio oficial. Para ello, añadiremos una nueva fuente de paquete, añadiremos la clave GPG de Docker para garantizar que las descargas sean válidas y, a continuación, instalaremos el paquete.

Primero, actualice su lista existente de paquetes:

sudo apt update

A continuación, instale algunos paquetes de requisitos previos que permitan aptutilizar paquetes a través de HTTPS:

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

Luego, agregue la clave GPG del repositorio oficial de Docker a su sistema:

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

Agregue el repositorio de Docker a las fuentes de APT:

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

Actualice nuevamente su lista existente de paquetes para que se reconozca la adición:

sudo apt update

Asegúrate de que estás a punto de instalar desde el repositorio de Docker en lugar del repositorio predeterminado de Ubuntu:

apt-cache policy docker-ce

Verá un resultado como este, aunque el número de versión de Docker puede ser diferente: Salida de la política apt-cache docker-ce

docker-ce:
  Installed: (none)
  Candidate: 5:20.10.14~3-0~ubuntu-jammy
  Version table:
     5:20.10.14~3-0~ubuntu-jammy 500
        500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
     5:20.10.13~3-0~ubuntu-jammy 500
        500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages

Tenga en cuenta que docker-ceno está instalado, pero el candidato para la instalación es del repositorio Docker para Ubuntu.

Por último, instala Docker:

sudo apt install docker-ce

Docker ya debería estar instalado, el demonio iniciado y el proceso habilitado para iniciarse al arrancar. Compruebe que se esté ejecutando:

sudo systemctl status docker

La salida debería ser similar a la siguiente, mostrando que el servicio está activo y en ejecución:

Output● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-04-01 21:30:25 UTC; 22s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 7854 (dockerd)
      Tasks: 7
     Memory: 38.3M
        CPU: 340ms
     CGroup: /system.slice/docker.service
             └─7854 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Al instalar Docker ahora, no solo obtendrá el servicio Docker (daemon), sino también la utilidad de línea de comandos o el cliente Docker. Más adelante en este tutorial, dockerveremos cómo usar el comando.docker

Paso 2: Ejecutar el comando Docker sin sudo (opcional)

De forma predeterminada, el dockercomando solo puede ser ejecutado por el usuario root o por un usuario del grupo Docker , que se crea automáticamente durante la instalación de Docker. Si intenta ejecutar el dockercomando sin prefijarlo con sudoo sin pertenecer al grupo Docker , obtendrá un resultado como este:

Outputdocker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.

Si desea evitar escribir sudocada vez que ejecuta el dockercomando, agregue su nombre de usuario al dockergrupo:

sudo usermod -aG docker ${USER}

Para aplicar la nueva membresía del grupo, cierre la sesión del servidor y vuelva a iniciarla, o escriba lo siguiente:

su - ${USER}

Se le pedirá que ingrese su contraseña de usuario para continuar.

Confirme que su usuario ahora está agregado al grupo Docker escribiendo:

groups
Outputsammy sudo docker

Si necesita agregar un usuario al dockergrupo con el que no ha iniciado sesión, declare ese nombre de usuario explícitamente usando:

sudo usermod -aG docker username

El resto de este artículo asume que está ejecutando el dockercomando como usuario del grupo Docker . Si no lo hace, anteponga “<nombre del usuario>” a los comandos sudo.

Exploremos el dockercomando a continuación.

Paso 3: Uso del comando Docker

Usar dockerconsiste en pasarle una cadena de opciones y comandos seguidos de argumentos. La sintaxis es la siguiente:

docker [option] [command] [arguments]

Para ver todos los subcomandos disponibles, escriba:

docker

A partir de la versión de Docker20.10.14La lista completa de subcomandos disponibles incluye:

Output  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Para ver las opciones disponibles para un comando específico, escriba:

docker docker-subcommand --help

Para ver información de todo el sistema sobre Docker, utilice:

docker info

Exploremos algunos de estos comandos. Empezaremos trabajando con imágenes.

Paso 4: Trabajar con imágenes de Docker

Los contenedores Docker se crean a partir de imágenes de Docker. Por defecto, Docker obtiene estas imágenes de Docker Hub , un registro de Docker gestionado por Docker, la empresa responsable del proyecto Docker. Cualquiera puede alojar sus imágenes de Docker en Docker Hub, por lo que la mayoría de las aplicaciones y distribuciones de Linux que necesite tendrán imágenes alojadas allí.

Para comprobar si puede acceder y descargar imágenes desde Docker Hub, escriba:

docker run hello-world

La salida indicará que Docker funciona correctamente:

OutputUnable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

...

Inicialmente, Docker no pudo encontrar la hello-worldimagen localmente, por lo que la descargó de Docker Hub, el repositorio predeterminado. Una vez descargada, Docker creó un contenedor a partir de ella y la aplicación dentro del contenedor se ejecutó, mostrando el mensaje.

Puedes buscar imágenes disponibles en Docker Hub usando el dockercomando con el searchsubcomando. Por ejemplo, para buscar la imagen de Ubuntu, escribe:

docker search ubuntu

El script rastreará Docker Hub y devolverá una lista de todas las imágenes cuyo nombre coincida con la cadena de búsqueda. En este caso, el resultado será similar a este:

OutputNAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                           Ubuntu is a Debian-based Linux operating sys…   14048     [OK]
websphere-liberty                WebSphere Liberty multi-architecture images …   283       [OK]
ubuntu-upstart                   DEPRECATED, as is Upstart (find other proces…   112       [OK]
neurodebian                      NeuroDebian provides neuroscience research s…   88        [OK]
open-liberty                     Open Liberty multi-architecture images based…   51        [OK]
...

En la columna OFICIAL , OK indica una imagen creada y respaldada por la empresa responsable del proyecto. Una vez identificada la imagen que desea usar, puede descargarla a su computadora con el pullsubcomando.

Ejecute el siguiente comando para descargar la ubuntuimagen oficial a su computadora:

docker pull ubuntu

Verá el siguiente resultado:

OutputUsing default tag: latest
latest: Pulling from library/ubuntu
e0b25ef51634: Pull complete
Digest: sha256:9101220a875cee98b016668342c489ff0674f247f6ca20dfc91b91c0f28581ae
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

Tras descargar una imagen, puede ejecutar un contenedor con ella mediante el runsubcomando. Como vio en el hello-worldejemplo, si no se ha descargado una imagen al dockerejecutar el runsubcomando, el cliente Docker primero la descargará y luego ejecutará un contenedor con ella.

Para ver las imágenes que se han descargado en tu ordenador, escribe:

docker images

El resultado será similar al siguiente:

OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              1d622ef86b13        3 weeks ago         73.9MB
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB

Como verá más adelante en este tutorial, las imágenes que utiliza para ejecutar contenedores se pueden modificar y usar para generar nuevas imágenes, que luego pueden cargarse ( el término técnico es “push “) en Docker Hub u otros registros de Docker.

Veamos cómo ejecutar contenedores con más detalle.

Paso 5: Ejecución de un contenedor Docker

El hello-worldcontenedor que ejecutaste en el paso anterior es un ejemplo de un contenedor que se ejecuta y finaliza tras emitir un mensaje de prueba. Los contenedores pueden ser mucho más útiles y pueden ser interactivos. Al fin y al cabo, son similares a las máquinas virtuales, solo que consumen menos recursos.

A modo de ejemplo, ejecutemos un contenedor con la imagen más reciente de Ubuntu. La combinación de las opciones -i y -t proporciona acceso interactivo al contenedor a través del shell:

docker run -it ubuntu

El símbolo del sistema debería cambiar para reflejar el hecho de que ahora está trabajando dentro del contenedor y debería adoptar este formato:

Outputroot@d9b100f2f636:/#

Anote el ID del contenedor en el símbolo del sistema. En este ejemplo, es d9b100f2f636. Necesitará ese ID más adelante para identificar el contenedor cuando desee eliminarlo.

Ahora puedes ejecutar cualquier comando dentro del contenedor. Por ejemplo, actualicemos la base de datos de paquetes dentro del contenedor. No necesitas prefijar ningún comando con sudo, ya que estás operando dentro del contenedor como usuario root :

apt update

Luego, instala cualquier aplicación. Instalemos Node.js:

apt install nodejs

Esto instala Node.js en el contenedor desde el repositorio oficial de Ubuntu. Al finalizar la instalación, verifique que Node.js esté instalado:

node -v

Verás el número de versión mostrado en tu terminal:

Outputv12.22.9

Cualquier cambio que realice dentro del contenedor sólo se aplicará a ese contenedor.

Para salir del contenedor, escriba exiten el aviso.

A continuación veamos cómo administrar los contenedores en nuestro sistema.

Paso 6: Administrar contenedores Docker

Después de usar Docker durante un tiempo, tendrás muchos contenedores activos (en ejecución) e inactivos en tu equipo. Para ver los activos , usa:

docker ps

Verá un resultado similar al siguiente:

OutputCONTAINER ID        IMAGE               COMMAND             CREATED

En este tutorial, iniciaste dos contenedores: uno desde la hello-worldimagen y otro desde la ubuntuimagen. Ambos contenedores ya no se ejecutan, pero aún existen en tu sistema.

Para ver todos los contenedores (activos e inactivos), ejecute docker psel -ainterruptor:

docker ps -a

Verá un resultado similar a este:

OutputCONTAINER ID   IMAGE         COMMAND   CREATED         STATUS                     PORTS     NAMES
1c08a7a0d0e4   ubuntu        "bash"     About a minute ago   Exited (0) 7 seconds ago             dazzling_taussig
587000e49d53   hello-world   "/hello"   5 minutes ago        Exited (0) 5 minutes ago             adoring_kowalevski

Para ver el último contenedor que ha creado, pásele el -linterruptor:

docker ps -l
OutputCONTAINER ID   IMAGE     COMMAND   CREATED         STATUS                     PORTS     NAMES
1c08a7a0d0e4   ubuntu    "bash"    3 minutes ago   Exited (0) 2 minutes ago             dazzling_taussig

Para iniciar un contenedor detenido, utilice docker start, seguido del ID o el nombre del contenedor. Iniciemos el contenedor basado en Ubuntu con el ID de 1c08a7a0d0e4:

docker start 1c08a7a0d0e4

El contenedor se iniciará y podrás usar docker pspara ver su estado:

OutputCONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
1c08a7a0d0e4   ubuntu    "bash"    6 minutes ago   Up 8 seconds             dazzling_taussig

Para detener un contenedor en ejecución, use docker stop, seguido del ID o nombre del contenedor. En esta ocasión, usaremos el nombre que Docker le asignó al contenedor, que es dazzling_taussig:

docker stop dazzling_taussig

Una vez que haya decidido que ya no necesita un contenedor, elimínelo con el docker rmcomando, usando nuevamente el ID o el nombre del contenedor. Use el docker ps -acomando para encontrar el ID o el nombre del contenedor asociado a la hello-worldimagen y elimínelo.

docker rm adoring_kowalevski

Puedes crear un nuevo contenedor y asignarle un nombre con el --namemodificador. También puedes usarlo --rmpara crear un contenedor que se elimine automáticamente al detenerse. Consulta el docker run helpcomando para obtener más información sobre estas y otras opciones.

Los contenedores se pueden convertir en imágenes que puedes usar para crear nuevos contenedores. Veamos cómo funciona.

Paso 7: Confirmar cambios en un contenedor a una imagen de Docker

Al iniciar una imagen de Docker, puedes crear, modificar y eliminar archivos igual que con una máquina virtual. Los cambios que realices solo se aplicarán a ese contenedor. Puedes iniciarlo y detenerlo, pero una vez que lo destruyas con el docker rmcomando, los cambios se perderán definitivamente.

Esta sección le muestra cómo guardar el estado de un contenedor como una nueva imagen de Docker.

Tras instalar Node.js en el contenedor de Ubuntu, tendrás un contenedor que se ejecuta a partir de una imagen, pero este contenedor es diferente de la imagen que usaste para crearlo. Sin embargo, podrías reutilizar este contenedor de Node.js como base para nuevas imágenes más adelante.

Luego, confirme los cambios en una nueva instancia de imagen de Docker usando el siguiente comando.

docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name

El parámetro -m se utiliza para el mensaje de confirmación que te ayuda a ti y a otros a saber qué cambios realizaste, mientras que -a se usa para especificar el autor. container_idEs el que anotaste anteriormente en el tutorial al iniciar la sesión interactiva de Docker. A menos que hayas creado repositorios adicionales en Docker Hub, repositorysuele ser tu nombre de usuario de Docker Hub.

Por ejemplo, para el usuario sammy , con el ID de contenedor de d9b100f2f636, el comando sería:

docker commit -m "added Node.js" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs

Al confirmar una imagen, esta se guarda localmente en tu ordenador. Más adelante en este tutorial, aprenderás a subir una imagen a un registro de Docker como Docker Hub para que otros usuarios puedan acceder a ella.

Al enumerar nuevamente las imágenes de Docker, se mostrará la nueva imagen, así como la antigua de la que se derivó:

docker images

Verás un resultado como este:

OutputREPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
sammy/ubuntu-nodejs   latest              7c1f35226ca6        7 seconds ago       179MB
...

En este ejemplo, ubuntu-nodejsse muestra la nueva imagen, derivada de la ubuntuimagen existente de Docker Hub. La diferencia de tamaño refleja los cambios realizados. En este ejemplo, el cambio fue la instalación de NodeJS. Así, la próxima vez que necesite ejecutar un contenedor en Ubuntu con NodeJS preinstalado, podrá usar la nueva imagen.

También puedes crear imágenes desde un archivo Dockerfile, lo que te permite automatizar la instalación de software en una nueva imagen. Sin embargo, esto queda fuera del alcance de este tutorial.

Ahora compartamos la nueva imagen con otros para que puedan crear contenedores a partir de ella.

Paso 8: Enviar imágenes de Docker a un repositorio de Docker

El siguiente paso lógico tras crear una imagen a partir de una existente es compartirla con algunos amigos, con todo el mundo en Docker Hub o en otro registro de Docker al que tengas acceso. Para subir una imagen a Docker Hub o a cualquier otro registro de Docker, debes tener una cuenta allí.

Para enviar su imagen, primero inicie sesión en Docker Hub.

docker login -u docker-registry-username

Se te pedirá que te autentiques con tu contraseña de Docker Hub. Si la especificaste correctamente, la autenticación debería ser correcta.

Nota: Si el nombre de usuario del registro de Docker es diferente del nombre de usuario local que usó para crear la imagen, deberá etiquetarla con el nombre de usuario del registro. Para el ejemplo del paso anterior, escriba:

docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs

Luego puedes enviar tu propia imagen usando:

docker push docker-registry-username/docker-image-name

Para enviar la ubuntu-nodejsimagen al repositorio sammy , el comando sería:

docker push sammy/ubuntu-nodejs

El proceso puede tardar algún tiempo en completarse mientras se cargan las imágenes, pero una vez completado, el resultado se verá así:

OutputThe push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed

...


Después de enviar una imagen a un registro, debería aparecer en el panel de su cuenta, como se muestra en la imagen a continuación.

Nueva lista de imágenes de Docker en Docker Hub

Si un intento de inserción da como resultado un error de este tipo, es probable que no haya iniciado sesión:

OutputThe push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Preparing
5f70bf18a086: Preparing
a3b5c80a4eba: Preparing
7f18b442972b: Preparing
3ce512daaf78: Preparing
7aae4540b42d: Waiting
unauthorized: authentication required

Inicia sesión con docker loginy repite el intento de envío. Luego, verifica que exista en la página del repositorio de Docker Hub.

Ahora puedes usarla para extraer la imagen a una nueva máquina y usarla para ejecutar un nuevo contenedor.docker pull sammy/ubuntu-nodejs

Instalación de Docker con soporte para GPU

Para instalar Docker con compatibilidad con GPU, deberá seguir un proceso ligeramente diferente al de la instalación estándar. Esto se debe a que la compatibilidad con GPU requiere controladores y configuraciones adicionales para que Docker pueda utilizar los recursos de la GPU. Estos son los pasos para instalar Docker con compatibilidad con GPU:

  • Asegúrese de que su sistema tenga una GPU NVIDIA compatible.
  • Instala el controlador NVIDIA para tu GPU. Puedes encontrar las instrucciones de instalación en el sitio web de NVIDIA .
  • Instale el nvidia-docker2paquete, que proporciona las herramientas necesarias para que Docker interactúe con la GPU NVIDIA.

Pasos de instalación

  • Agregue el repositorio Docker de NVIDIA:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
  • Actualice su lista de paquetes e instale el nvidia-docker2paquete:
sudo apt update && sudo apt install nvidia-docker2
  • Reinicie el servicio Docker para aplicar los cambios:
sudo service docker restart
  • Verifique que el entorno de ejecución de NVIDIA esté disponible:
sudo docker info | grep Runtime

Esto debería mostrar el tiempo de ejecución de NVIDIA como un tiempo de ejecución disponible.

Uso de la compatibilidad con GPU

Para usar la compatibilidad con GPU con tus contenedores Docker, deberás especificar el --gpusindicador al ejecutar el contenedor. Por ejemplo:

sudo docker run --gpus all nvidia/cuda:10.2-base nvidia-smi

Este comando ejecuta un contenedor con la imagen NVIDIA CUDA y ejecuta el nvidia-smicomando para verificar la compatibilidad con la GPU.

Para obtener más información sobre la instalación y el uso de Docker con soporte de GPU, consulte los siguientes recursos:

Si sigue estos pasos y utiliza los recursos proporcionados, podrá instalar y utilizar con éxito Docker con soporte de GPU en su sistema.

Configuración de las mejores prácticas de seguridad de Docker

La seguridad de Docker Engine es crucial para garantizar que sus contenedores y el sistema host estén protegidos contra posibles vulnerabilidades. A continuación, se indican algunas prácticas recomendadas:

  • Utilice el principio de mínimo privilegio : asegúrese de que sus contenedores se ejecuten con los mínimos privilegios necesarios para realizar sus tareas.
  • Utilice un usuario que no sea root : ejecute sus contenedores como un usuario que no sea root para limitar la superficie de ataque en caso de una violación.
  • Mantenga su versión de Docker actualizada : actualice periódicamente su versión de Docker para asegurarse de tener los últimos parches de seguridad.
  • Usar Docker Content Trust : habilite Docker Content Trust para garantizar la integridad de las imágenes que extrae de Docker Hub.
  • Limitar la exposición de la red : exponga únicamente los puertos necesarios a la red para minimizar la superficie de ataque.

Uso de Docker Compose

Docker Compose es una herramienta para definir y ejecutar aplicaciones Docker multicontenedor. Permite definir los servicios que componen la aplicación y cómo interactúan entre sí. Estas son algunas ventajas de usar Docker Compose:

  • Implementación simplificada de aplicaciones : Docker Compose simplifica el proceso de implementación de aplicaciones multicontenedor.
  • Gestión sencilla de servicios : Docker Compose le permite iniciar, detener y escalar sus servicios fácilmente.
  • Control de versiones : los archivos de Docker Compose pueden controlarse por versiones, lo que facilita el seguimiento de los cambios en la configuración de su aplicación.

Eliminación de paquetes de Docker

Eliminar paquetes de Docker es esencial para mantener el sistema y garantizar que tenga instaladas las últimas versiones de Docker. A continuación, se indican algunos pasos a seguir:

  • Enumerar todos los paquetes Docker instalados : utilice el comando dpkg -l | grep dockerpara enumerar todos los paquetes Docker instalados.
  • Eliminar el paquete Docker : utilice el comando sudo apt remove docker-cepara eliminar el paquete Docker.
  • Eliminar dependencias de Docker : use el comando sudo apt autoremovepara eliminar cualquier dependencia que ya no sea necesaria.
  • Actualice su lista de paquetes : use el comando sudo apt updatepara actualizar su lista de paquetes después de eliminar los paquetes de Docker.

Las imágenes, contenedores, volúmenes o archivos de configuración personalizados de su host no se eliminan automáticamente. Para eliminar todas las imágenes, contenedores y volúmenes:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Eliminar lista de fuentes y llaveros:

sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /etc/apt/keyrings/docker.asc

Errores comunes y depuración

El demonio Docker no se inicia

Si el demonio de Docker no se inicia, puede deberse a varias razones, como problemas de configuración, conflictos con otros servicios o limitaciones de recursos del sistema. Para solucionar este problema, puede que vea mensajes de error como:

OutputFailed to start Docker Application Container Engine.

o

Outputdocker.service: Main process exited, code=exited, status=1/FAILURE

Para resolver este problema:

  1. Compruebe el estado del servicio Docker:sudo systemctl status docker
  2. Revise los registros de Docker para detectar errores:sudo journalctl -u docker
  3. Asegúrese de que el servicio Docker esté habilitado para iniciarse en el arranque:sudo systemctl enable docker
  4. Reinicie el servicio Docker:sudo systemctl restart docker

Errores de permisos al ejecutar comandos de Docker

Los errores de permisos ocurren cuando el usuario que ejecuta comandos de Docker no tiene suficientes privilegios. Para solucionar este problema, puede observar mensajes de error como:

Outputdocker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.

Para resolver este problema:

  1. Asegúrese de que el usuario sea parte del dockergrupo:sudo usermod -aG docker ${USER}
  2. Cierre sesión y vuelva a iniciarla para aplicar los cambios de membresía del grupo
  3. Alternativamente, utilice sudoantes de ejecutar los comandos de Docker:sudo docker <command>

Si sigue estos pasos, debería poder resolver errores comunes relacionados con el demonio Docker que no se inicia y errores de permisos al ejecutar comandos Docker.

Preguntas frecuentes

¿Cómo instalo Docker en Ubuntu 22.04?

Para instalar Docker en Ubuntu , siga estos pasos:

  1. Actualice su lista de paquetes:sudo apt update
  2. Instalar los paquetes necesarios:sudo apt install apt-transport-https ca-certificates curl software-properties-common
  3. Agregue la clave GPG de Docker:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  4. Agregue el repositorio de Docker:echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  5. Actualice su lista de paquetes nuevamente:sudo apt update
  6. Instalar Docker:sudo apt install docker-ce

¿Cómo verifico que Docker esté instalado en Ubuntu?

Para verificar que Docker esté instalado en Ubuntu, ejecute el siguiente comando:sudo systemctl status docker

Este comando le mostrará el estado del servicio Docker. Si Docker está instalado y en ejecución, debería ver un resultado que indique que el servicio está activo y en ejecución. A continuación, se muestra un ejemplo de lo que podría ver:

Output● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2025-04-08 21:30:25 UTC; 22s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 7854 (dockerd)
      Tasks: 7
     Memory: 38.3M
        CPU: 340ms
     CGroup: /system.slice/docker.service
             └─7854 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

¿Cómo ejecuto Docker sin sudo?

Para ejecutar Docker sin usar sudo, debes agregar tu usuario al dockergrupo. Así es como se hace:

  1. Añade tu usuario al dockergrupo:sudo usermod -aG docker ${USER}
  2. Cierre sesión y vuelva a iniciarla para aplicar los cambios.

Después de agregar su usuario al dockergrupo, debería poder ejecutar comandos de Docker sin usar sudo.

¿Cómo desinstalo Docker de Ubuntu?

Para desinstalar Docker de Ubuntu , siga estos pasos:

  1. Detener el servicio Docker:sudo systemctl stop docker
  2. Eliminar paquetes de Docker:sudo apt purge docker-ce
  3. Eliminar dependencias de Docker:sudo apt autoremove
  4. Eliminar el repositorio de Docker:sudo rm /etc/apt/sources.list.d/docker.list

Conclusión

En este tutorial, instalaste Docker, trabajaste con imágenes y contenedores, y subiste una imagen modificada a Docker Hub. Ahora que conoces los conceptos básicos, explora. Para configuraciones de Docker más avanzadas, considera los siguientes tutoriales:

Stephen Dove
Comments

March 25, 2025

Cómo agregar espacio de intercambio en Ubuntu 22.04

Introducción

Una forma de evitar errores de memoria insuficiente en las aplicaciones es añadir espacio de intercambio al servidor. En esta guía, explicaremos cómo añadir un archivo de intercambio a un servidor Ubuntu 22.04.

¿Qué es Swap?

El espacio de intercambio (swap) es una porción del almacenamiento del disco duro que el sistema operativo reserva para almacenar temporalmente los datos que ya no puede almacenar en la RAM. Esto permite aumentar la cantidad de información que el servidor puede almacenar en su memoria de trabajo, con algunas salvedades. El espacio de intercambio del disco duro se utiliza principalmente cuando ya no hay suficiente espacio en la RAM para almacenar los datos de las aplicaciones en uso.

La información escrita en el disco será significativamente más lenta que la almacenada en la RAM, pero el sistema operativo preferirá mantener los datos de las aplicaciones en ejecución en memoria y usar la memoria de intercambio (swap) para los datos más antiguos. En general, tener espacio de intercambio como respaldo cuando la RAM del sistema se agote puede ser una buena protección contra excepciones de falta de memoria en sistemas con almacenamiento no SSD disponible.

Paso 1: Verificación del sistema para obtener información de intercambio

Antes de comenzar, podemos comprobar si el sistema ya tiene espacio de intercambio disponible. Es posible tener varios archivos o particiones de intercambio, pero generalmente uno debería ser suficiente.

Podemos ver si el sistema tiene algún swap configurado escribiendo:

sudo swapon --show

Si no obtiene ningún resultado, significa que su sistema no tiene espacio de intercambio disponible actualmente.

Puedes verificar que no haya ningún intercambio activo usando la freeutilidad:

free -h

Output              total        used        free      shared  buff/cache   available
Mem:          981Mi       122Mi       647Mi       0.0Ki       211Mi       714Mi
Swap:            0B          0B          0B

Como puede ver en la fila Swap de la salida, no hay ningún swap activo en el sistema.

Paso 2: Verificar el espacio disponible en la partición del disco duro

Antes de crear nuestro archivo de intercambio, comprobaremos el uso actual del disco para asegurarnos de que tengamos suficiente espacio. Para ello, introduzca:

df -h

OutputFilesystem      Size  Used Avail Use% Mounted on
udev            474M     0  474M   0% /dev
tmpfs            99M  932K   98M   1% /run
/dev/vda1        25G  1.4G   23G   7% /
tmpfs           491M     0  491M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           491M     0  491M   0% /sys/fs/cgroup
/dev/vda15      105M  3.9M  101M   4% /boot/efi
/dev/loop0       55M   55M     0 100% /snap/core18/1705
/dev/loop1       69M   69M     0 100% /snap/lxd/14804
/dev/loop2       28M   28M     0 100% /snap/snapd/7264
tmpfs            99M     0   99M   0% /run/user/1000

En este caso, el dispositivo /en la Mounted oncolumna es nuestro disco. Tenemos mucho espacio disponible (solo se utilizan 1,4 GB). Tu uso probablemente será diferente.

Aunque existen diversas opiniones sobre el tamaño adecuado del espacio de intercambio, en realidad depende de tus preferencias personales y de los requisitos de tu aplicación. Generalmente, un buen punto de partida es una cantidad igual o el doble de la RAM de tu sistema. Otra regla general es que cualquier cantidad superior a 4 GB de espacio de intercambio probablemente sea innecesaria si solo la usas como RAM de reserva.

Paso 3: Creación de un archivo de intercambio

Ahora que conocemos el espacio disponible en el disco duro, podemos crear un archivo de intercambio en nuestro sistema de archivos. Asignaremos un archivo del tamaño que queramos llamar en nuestro directorio swapfileraíz ( )./

La mejor manera de crear un archivo de intercambio es con el fallocateprograma. Este comando crea instantáneamente un archivo del tamaño especificado.

Dado que el servidor de nuestro ejemplo tiene 1 GB de RAM, crearemos un archivo de 1 GB en esta guía. Ajústelo según las necesidades de su servidor:

sudo fallocate -l 1G /swapfile

Podemos verificar que se reservó la cantidad correcta de espacio escribiendo:

ls -lh /swapfile

-rw-r--r-- 1 root root 1.0G Apr 25 11:14 /swapfile

Nuestro archivo ha sido creado con la cantidad correcta de espacio reservado.

Paso 4 – Habilitación del archivo de intercambio

Ahora que tenemos disponible un archivo del tamaño correcto, necesitamos convertirlo en espacio de intercambio.

Primero, necesitamos restringir los permisos del archivo para que solo los usuarios con privilegios de root puedan leer su contenido. Esto impide que los usuarios normales accedan al archivo, lo que tendría importantes consecuencias para la seguridad.

Haga que el archivo sólo sea accesible para root escribiendo:

sudo chmod 600 /swapfile

Verifique el cambio de permisos escribiendo:

ls -lh /swapfile

Output-rw------- 1 root root 1.0G Apr 25 11:14 /swapfile

Como puede ver, solo el usuario root tiene habilitadas las funciones de lectura y escritura.

Ahora podemos marcar el archivo como espacio de intercambio escribiendo:

sudo mkswap /swapfile

OutputSetting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=6e965805-2ab9-450f-aed6-577e74089dbf

Luego de marcar el archivo, podemos habilitar el archivo de intercambio, permitiendo que nuestro sistema comience a usarlo:

sudo swapon /swapfile

Verifique que el intercambio esté disponible escribiendo:

sudo swapon --show

OutputNAME      TYPE  SIZE USED PRIO
/swapfile file 1024M   0B   -2

Podemos verificar freenuevamente la salida de la utilidad para corroborar nuestros hallazgos:

free -h

Output              total        used        free      shared  buff/cache   available
Mem:          981Mi       123Mi       644Mi       0.0Ki       213Mi       714Mi
Swap:         1.0Gi          0B       1.0Gi

Nuestro intercambio se ha configurado correctamente y nuestro sistema operativo comenzará a usarlo según sea necesario.

Paso 5 – Hacer que el archivo de intercambio sea permanente

Nuestros cambios recientes han habilitado el archivo de intercambio para la sesión actual. Sin embargo, si reiniciamos, el servidor no conservará la configuración de intercambio automáticamente. Podemos cambiar esto añadiendo el archivo de intercambio a nuestro /etc/fstabarchivo.

Haga una copia de seguridad del /etc/fstabarchivo en caso de que algo salga mal:

sudo cp /etc/fstab /etc/fstab.bak

Agregue la información del archivo de intercambio al final de su /etc/fstabarchivo escribiendo:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

A continuación revisaremos algunas configuraciones que podemos actualizar para ajustar nuestro espacio de intercambio.

Paso 6 – Ajuste de la configuración de intercambio

Hay algunas opciones que puedes configurar y que tendrán un impacto en el rendimiento de tu sistema al trabajar con intercambio.

Ajuste de la propiedad de swappiness

Este swappinessparámetro configura la frecuencia con la que el sistema intercambia datos de la RAM al espacio de intercambio. Este valor, entre 0 y 100, representa un porcentaje.

Con valores cercanos a cero, el kernel no intercambiará datos con el disco a menos que sea absolutamente necesario. Recuerde que las interacciones con el archivo de intercambio son costosas, ya que tardan mucho más que las interacciones con la RAM y pueden causar una reducción significativa del rendimiento. Indicarle al sistema que no dependa demasiado del archivo de intercambio generalmente lo hará más rápido.

Los valores cercanos a 100 intentarán almacenar más datos en la memoria de intercambio para liberar más espacio de RAM. Dependiendo del perfil de memoria de sus aplicaciones o del uso que le dé al servidor, esto podría ser mejor en algunos casos.

Podemos ver el valor de swappiness actual escribiendo:

cat /proc/sys/vm/swappiness

Output60

Para una computadora de escritorio, un valor de swappiness de 60 no es un mal valor. Para un servidor, conviene acercarlo a 0.

Podemos establecer el swappiness a un valor diferente usando el sysctlcomando.

Por ejemplo, para establecer el swappiness a 10, podríamos escribir:

sudo sysctl vm.swappiness=10

Outputvm.swappiness = 10

Esta configuración se mantendrá hasta el próximo reinicio. Podemos configurar este valor automáticamente al reiniciar añadiendo la siguiente línea a nuestro /etc/sysctl.confarchivo:

sudo nano /etc/sysctl.conf

En la parte inferior puedes agregar: /etc/sysctl.conf

vm.swappiness=10

Guarde y cierre el archivo cuando haya terminado.

Ajuste de la configuración de presión de caché

Otro valor relacionado que podrías querer modificar es el vfs_cache_pressure. Esta configuración configura con qué frecuencia el sistema almacenará en caché la información de inodos y entradas de entrada sobre otros datos.

Básicamente, se trata de datos de acceso al sistema de archivos. Su consulta suele ser muy costosa y se solicita con mucha frecuencia, por lo que es excelente almacenarlos en caché. Puede ver el valor actual consultando procde nuevo el sistema de archivos:

cat /proc/sys/vm/vfs_cache_pressure

Output100

Con la configuración actual, nuestro sistema elimina la información de inodos de la caché demasiado rápido. Podemos configurarlo con un valor más conservador, como 50, escribiendo:

sudo sysctl vm.vfs_cache_pressure=50

Outputvm.vfs_cache_pressure = 50

Nuevamente, esto solo es válido para nuestra sesión actual. Podemos cambiarlo añadiéndolo a nuestro archivo de configuración, como hicimos con la configuración de intercambio:

sudo nano /etc/sysctl.conf

En la parte inferior, agregue la línea que especifica su nuevo valor: /etc/sysctl.conf

vm.vfs_cache_pressure=50

Guarde y cierre el archivo cuando haya terminado.

Conclusión

Seguir los pasos de esta guía le dará un respiro en casos que, de otro modo, provocarían excepciones de memoria insuficiente. El espacio de intercambio puede ser increíblemente útil para evitar algunos de estos problemas comunes.

Si se encuentra con errores OOM (sin memoria) o descubre que su sistema no puede utilizar las aplicaciones que necesita, la mejor solución es optimizar las configuraciones de sus aplicaciones o actualizar su servidor.

Stephen Dove
Comments

March 22, 2025

Cómo instalar una interfaz gráfica de usuario en un servidor Ubuntu: guía paso a paso

Introduccion

Ubuntu Server está diseñado principalmente para funcionar sin interfaz gráfica, lo que lo hace ligero y optimizado para su uso en servidores. Sin embargo, en ciertas situaciones, una GUI puede simplificar la administración del sistema, especialmente para usuarios que no están familiarizados con la línea de comandos. En este tutorial, te guiaré en el proceso de instalación de una GUI en Ubuntu Server .

Prerrequisitos

Antes de continuar con la instalación, asegúrese de tener lo siguiente:

  1. El último servidor Ubuntu instalado .
  2. Una cuenta de usuario con sudo privilegios .
  3. Una conexión a Internet activa.

Instalación de una interfaz gráfica de usuario (GUI) en el servidor Ubuntu

Paso 1: Actualice su sistema

Antes de instalar cualquier software, es fundamental asegurarse de que su sistema esté actualizado. Ejecute los siguientes comandos para actualizar las listas de paquetes y actualizar los paquetes obsoletos:

sudo apt update
sudo apt upgrade -y

Esto garantiza que tenga instalados los últimos parches de seguridad y actualizaciones del sistema.

Paso 2: Elige un entorno de escritorio

Ubuntu ofrece diversos entornos de escritorio que se adaptan a diferentes necesidades y preferencias de rendimiento. Estos son algunos de los más populares:

  • GNOME: el entorno de escritorio predeterminado para Ubuntu Desktop.
  • Xfce (Xubuntu): ligero y eficiente en el uso de recursos.
  • LXDE (Lubuntu): Extremadamente liviano, ideal para hardware de bajas especificaciones.
  • KDE (Kubuntu): un entorno rico en características que podría utilizar más recursos.

En este tutorial, nos centraremos en la instalación de GNOME y Xfce, pero puedes elegir cualquiera de los otros reemplazando el nombre del paquete en los siguientes pasos.

Paso 3: Instalar el entorno de escritorio

Instalación de GNOME

Si prefiere la experiencia completa del escritorio Ubuntu, puede instalar el entorno de escritorio GNOME. Ejecute el siguiente comando:

sudo apt install ubuntu-desktop -y

Esto instalará el escritorio GNOME completo, junto con todas sus aplicaciones asociadas, que pueden consumir muchos recursos.

Instalación de Xfce

Si necesitas una opción más ligera, Xfce es una excelente opción. Para instalarlo, ejecuta:

sudo apt install xubuntu-core -y

Esto instala el entorno de escritorio Xfce sin aplicaciones innecesarias, lo que lo convierte en una opción más minimalista y eficiente para los servidores.

Instalación de otros escritorios

Puede instalar otros entornos de escritorio como LXDE o KDE ejecutando:

# For LXDE
sudo apt install lubuntu-core -y


# For KDE Plasma
sudo apt install kubuntu-desktop -y

Paso 4: Instalar un administrador de pantalla

Un administrador de pantalla se encarga de iniciar el entorno de escritorio. Ubuntu usa GDM (Administrador de Pantalla de GNOME) por defecto, pero puedes instalar otros como LightDM para una opción más ligera, especialmente si usas Xfce o LXDE.

Para instalar LightDM, ejecute:

sudo apt install lightdm -y

Durante la instalación, se le pedirá que seleccione un administrador de pantalla predeterminado. Si no está seguro, LightDM es una buena opción, especialmente para entornos ligeros como Xfce.

Paso 5: Habilite la GUI para que se inicie automáticamente

Una vez completada la instalación, deberá configurar su sistema para que inicie la GUI automáticamente.

Primero, verifique el objetivo predeterminado del sistema, que determina qué servicios se inician cuando se inicia el sistema:

systemctl get-default

Por defecto, debería devolver multi-user.target, que corresponde al modo no gráfico. Para cambiar al modo gráfico, ejecute:

sudo systemctl set-default graphical.target

Ahora, su servidor se iniciará en la interfaz gráfica automáticamente en el próximo inicio.

Paso 6: Reiniciar el sistema

Una vez que haya instalado el entorno de escritorio y lo haya configurado para que se inicie automáticamente, reinicie su sistema para aplicar los cambios:

sudo reboot

Después de reiniciar, debería aparecer la pantalla de inicio de sesión del entorno de escritorio que instaló (GNOME, Xfce, etc.).

Paso 7: Conectarse a la GUI (opcional)

Si administra su servidor de forma remota, puede usar una conexión de escritorio remoto para acceder a la interfaz gráfica de usuario. Estas son algunas opciones populares:

Consola en la nube : Tu proveedor de nube probablemente ya cuente con una función de consola que te permite conectarte a tu servidor. Si usas servidores Cherry , selecciona tu máquina virtual en el portal del cliente y haz clic en Consolepara acceder a la consola de tu servidor.

Luego puede iniciar sesión a través de la GUI y acceder a su escritorio:

VNC : Una opción popular para conexiones de escritorio remoto. Para instalar un servidor VNC, ejecute:

sudo apt install tightvncserver -y

RDP (Protocolo de Escritorio Remoto) : RDP es un protocolo de Microsoft para conexiones remotas, compatible con Ubuntu. Para instalar un servidor RDP, ejecute:

sudo apt install xrdp -y

Después de instalar su servidor de escritorio remoto preferido, configúrelo según sus necesidades y conéctese usando su máquina local.

Es posible que necesite configurar su firewall para permitir el acceso a su servidor VNC o RDP.

Paso 8: Administrar la GUI

Si alguna vez desea volver a un entorno no gráfico, puede cambiar el objetivo predeterminado a multi-user.target:

sudo systemctl set-default multi-user.target

Esto garantizará que su servidor arranque en la interfaz

de línea de comandos (CLI) de manera predeterminada.

#Conclusión

En este tutorial, explicamos cómo instalar una interfaz gráfica de usuario (GUI) en Ubuntu Server. Esto simplifica las tareas para quienes prefieren una interfaz gráfica. Ya sea que elija GNOME, con sus numerosas funciones, o Xfce, un sistema ligero, ahora sabe cómo instalar, configurar y administrar una GUI en su servidor. Tenga en cuenta que usar una GUI consume más recursos del sistema y puede afectar el rendimiento, especialmente en servidores de producción.

Stephen Dove