Etiqueta: Linux (Página 1 de 2)

Gestión de interfaces con nmcli

La utilidad nmcli (NetworkManager Command Line Interface) es utilizada para gestionar el estado de las redes. Con esta herramienta podemos, crear, editar, activar, eliminar y desactivar conexiones de red. Aprender el uso de esta herramienta es necesario ya que las nuevas versiones de Red Hat (9) y sus Forks (Rocky y Alma) han depreciado el funcionamiento de las interfaces ifcfg.

La sintaxis para usar este comando es la siguiente:

nmcli [OPTIONS] OBJECT { COMMAND | help }

Listar información de las interfaces

[tusysadmin@lab ~]$ sudo nmcli con show
NAME      UUID                                  TYPE      DEVICE
cableada  8531cd56-9e22-3a04-9f99-44ca92be00c4  ethernet  eno1
lo        3115100c-122b-482b-8653-fe4802d55f2e  loopback  lo
SSID      51229f3b-5809-439e-a328-5b641b1a80ee  wifi      wlp0s20f0u2i2
virbr0    88690a18-991b-4ec5-81fb-83bdc24aca57  bridge    virbr0

Las interfaces mostradas son de un equipo con cuenta con wifi y cable de red activos, la interfaz virbr0 corresponde al servicio de libvirtd ya que el mencionado dispositivo es un anfitrión de maquinas virtuales. De ser necesario, puede mostrarse la información de una interfaz en concreto:

[tusysadmin@lab ~]$ sudo nmcli con show id cableada
connection.id:                          cableada
connection.uuid:                        8531cd56-9e22-3a04-9f99-44ca92be00c4
connection.stable-id:                   --
connection.interface-name:              eno1
connection.autoconnect:                 sí
------
IP4.ADDRESS[1]:                         192.168.1.21/24
IP4.GATEWAY:                            192.168.1.1

Establecer IP

[tusysadmin@lab ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 10:62:e5:19:83:60 brd ff:ff:ff:ff:ff:ff
    altname enp0s31f6
    inet 192.168.1.21/24 brd 192.168.1.255 scope global dynamic noprefixroute eno1
       valid_lft 71830sec preferred_lft 71830sec
    inet6 fe80::4845:e957:bf2b:b3f4/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: wlp0s20f0u2i2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e0:e1:a9:3a:60:e4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.20/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp0s20f0u2i2
       valid_lft 71830sec preferred_lft 71830sec
    inet6 fe80::b145:75ae:fc15:38f4/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

[tusysadmin@lab ~]$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    100    0        0 eno1
default         _gateway        0.0.0.0         UG    600    0        0 wlp0s20f0u2i2
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eno1
192.168.1.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp0s20f0u2i2
192.168.124.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
Ipaddress = 192.168.1.15
Netmask   = 255.255.255.0
Gateway   = 192.168.1.1
DNS       = 80.80.80.80
[tusysadmin@lab ~]$ sudo nmcli con modify cableada ipv4.method manual
[tusysadmin@lab ~]$ sudo nmcli con modify cableada ipv4.addresses 192.168.1.15/24
[tusysadmin@lab ~]$ sudo nmcli con modify cableada ipv4.gateway 192.168.1.1
[tusysadmin@lab ~]$ sudo nmcli con modify cableada ipv4.dns 80.80.80.80
[tusysadmin@lab ~]$ sudo nmcli con up cableada
Conexión activada con éxito (ruta activa D-Bus: /org/freedesktop/NetworkManager/ActiveConnection/7)
[tusysadmin@lab ~]$
[tusysadmin@lab ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 10:62:e5:19:83:60 brd ff:ff:ff:ff:ff:ff
    altname enp0s31f6
    inet 192.168.1.15/24 brd 192.168.1.255 scope global noprefixroute eno1
       valid_lft forever preferred_lft forever
    inet6 fe80::4845:e957:bf2b:b3f4/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[tusysadmin@lab ~]$ ping -c3 google.com
PING google.com (142.250.74.206) 56(84) bytes of data.
64 bytes from fra24s02-in-f14.1e100.net (142.250.74.206): icmp_seq=1 ttl=48 time=152 ms
64 bytes from fra24s02-in-f14.1e100.net (142.250.74.206): icmp_seq=2 ttl=48 time=152 ms
64 bytes from fra24s02-in-f14.1e100.net (142.250.74.206): icmp_seq=3 ttl=48 time=152 ms

--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 151.663/151.773/151.925/0.111 ms
[tusysadmin@lab ~]$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    100    0        0 eno1
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eno1
[tusysadmin@lab ~]$ nslookup google.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	google.com
Address: 142.250.74.206
Name:	google.com
Address: 2a00:1450:4001:803::200e

[tusysadmin@lab ~]$

Virtualizar en Mac

Si por alguna razón cuentas con un equipo de la marca de la manzana y buscas una alternativa para virtualizar, te recomiendo Lima ya que a diferencia de otros proyectos funciona en las arquitectura x86_64 y ARM 64.

Lima utiliza QEMU para virtualizar, la gestión se realiza a través de la linea de comandos por lo que si estás buscando una alternativa gráfica o una maquina virtual con interfaz te recomiendo UTM que funciona igualmente con QEMU.

Instalación

Para la instalación de Lima utilizaremos el gestor de paquetes de Mac llamado Homebrew, sino cuentas con él puedes instalarlo de manera fácil de la siguiente forma:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Una vez instalado el gestor de paquetes podremos instalar Lima.

$ brew install lima

Lima utiliza archivos yaml para la creación de maquinas virtuales, existe una lista de templates que pueden usarse para desplegar nuestras maquinas, estos archivos los podemos localizar en el directorio, /opt/homebrew/share/lima/templates.

Administración

Crearemos una maquina virtual con ubuntu como imagen linux y asignaremos 2 gigas de memoria y 2 cpus.

personal-mac:templates tusysadmin$ pwd
/opt/homebrew/share/lima/templates

personal-mac:templates tusysadmin$ limactl create --name linux-server --set='.cpus = 2 | .memory = "2GiB"' ubuntu-lts.yaml
? Creating an instance "linux-server" Proceed with the current configuration
INFO[0001] Attempting to download the image              arch=aarch64 digest="sha256:5167c1b13cb33274955e36332ecb7b14f02b71fd19a37a9c1a3a0f8a805ab8e5" location="https://cloud-images.ubuntu.com/releases/22.04/release-20231010/ubuntu-22.04-server-cloudimg-arm64.img"
INFO[0001] Using cache "/Users/tusysadmin/Library/Caches/lima/download/by-url-sha256/f55d2d250bd1df34e6c082a8cbfea153f1ef6a5ec8a7300dd0ab8cbc13ec946b/data"
INFO[0002] Attempting to download the nerdctl archive    arch=aarch64 digest="sha256:ea30ab544c057e3a0457194ecd273ffbce58067de534bdfaffe4edf3a4da6357" location="https://github.com/containerd/nerdctl/releases/download/v1.6.2/nerdctl-full-1.6.2-linux-arm64.tar.gz"
INFO[0002] Using cache "/Users/tusysadmin/Library/Caches/lima/download/by-url-sha256/21921213c0426e38e2f26d2844446767e2a19c0b6655c774f9e4adbb5c368d8f/data"
INFO[0002] Run `limactl start linux-server` to start the instance.

Iniciemos la maquina.

personal-mac:templates tusysadmin$ limactl start linux-server
INFO[0000] Using the existing instance "linux-server"
INFO[0000] QEMU binary "/opt/homebrew/bin/qemu-system-aarch64" seems properly signed with the "com.apple.security.hypervisor" entitlement
INFO[0001] [hostagent] hostagent socket created at /Users/tusysadmin/.lima/linux-server/ha.sock
INFO[0001] [hostagent] Starting QEMU (hint: to watch the boot progress, see "/Users/tusysadmin/.lima/linux-server/serial*.log")
INFO[0001] SSH Local Port: 50965
INFO[0001] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
INFO[0018] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
INFO[0028] [hostagent] Waiting for the essential requirement 1 of 5: "ssh"
INFO[0029] [hostagent] The essential requirement 1 of 5 is satisfied
INFO[0029] [hostagent] Waiting for the essential requirement 2 of 5: "user session is ready for ssh"
INFO[0029] [hostagent] The essential requirement 2 of 5 is satisfied
INFO[0029] [hostagent] Waiting for the essential requirement 3 of 5: "sshfs binary to be installed"
INFO[0038] [hostagent] The essential requirement 3 of 5 is satisfied
INFO[0038] [hostagent] Waiting for the essential requirement 4 of 5: "/etc/fuse.conf (/etc/fuse3.conf) to contain \"user_allow_other\""
INFO[0041] [hostagent] The essential requirement 4 of 5 is satisfied
INFO[0041] [hostagent] Waiting for the essential requirement 5 of 5: "the guest agent to be running"
INFO[0041] [hostagent] The essential requirement 5 of 5 is satisfied
INFO[0041] [hostagent] Mounting "/Users/tusysadmin" on "/Users/tusysadmin"
INFO[0041] [hostagent] Mounting "/tmp/lima" on "/tmp/lima"
INFO[0041] [hostagent] Waiting for the optional requirement 1 of 2: "systemd must be available"
INFO[0041] [hostagent] Forwarding "/run/lima-guestagent.sock" (guest) to "/Users/tusysadmin/.lima/linux-server/ga.sock" (host)
INFO[0041] [hostagent] The optional requirement 1 of 2 is satisfied
INFO[0041] [hostagent] Waiting for the optional requirement 2 of 2: "containerd binaries to be installed"
INFO[0041] [hostagent] Not forwarding TCP 127.0.0.53:53
INFO[0041] [hostagent] Not forwarding TCP 0.0.0.0:22
INFO[0041] [hostagent] Not forwarding TCP [::]:22
INFO[0047] [hostagent] The optional requirement 2 of 2 is satisfied
INFO[0047] [hostagent] Waiting for the final requirement 1 of 1: "boot scripts must have finished"
INFO[0057] [hostagent] The final requirement 1 of 1 is satisfied
INFO[0057] READY. Run `limactl shell linux-server` to open the shell.

Para entrar a la maquina.

personal-mac:~ tusysadmin$ limactl shell linux-server

tusysadmin@lima-linux-server:/Users/tusysadmin$ sudo su -

root@lima-linux-server:~# apt-get update
Hit:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
Get:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease [119 kB]
Hit:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
Get:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease [110 kB]
Get:5 http://ports.ubuntu.com/ubuntu-ports jammy-updates/main arm64 Packages [1021 kB]
Get:6 http://ports.ubuntu.com/ubuntu-ports jammy-updates/main Translation-en [248 kB]
Get:7 http://ports.ubuntu.com/ubuntu-ports jammy-updates/universe arm64 Packages [917 kB]
Fetched 2415 kB in 4s (567 kB/s)
Reading package lists... Done
root@lima-linux-server:~# htop

root@lima-linux-server:~# cat /etc/issue
Ubuntu 22.04.3 LTS \n \l

Al salir de la maquina virtual podemos listar el resto de equipos y el estado en el que se encuentran.

personal-mac:~ tusysadmin$ limactl list
NAME            STATUS     SSH                VMTYPE    ARCH       CPUS    MEMORY    DISK      DIR
docker          Stopped    127.0.0.1:0        qemu      aarch64    4       4GiB      100GiB    ~/.lima/docker
linux-server    Running    127.0.0.1:49404    qemu      aarch64    2       2GiB      100GiB    ~/.lima/linux-server
personal-mac:~ tusysadmin$

Para explorar más opciones de administración podemos usar el comando limactl -h.

Crear contenedor desde archivo

Como ya lo hemos mencionado, las imágenes de los contenedores las podemos encontrar en el repositorio Docker Hub. Sin embargo; en ocasiones querremos usar nuestras propias aplicaciones o simplemente adaptarlo a nuestras necesidades.

Para hacer eso requerimos crear un Dockerfile, el siguiente archivo nos ayudara a crear un contenedor que ejecutara un archivo bash.

FROM ubuntu

LABEL maintainer="Tusysadmin.net"

USER root

COPY ./primer_archivo.bash /

RUN apt -y update
RUN apt -y install curl bash
RUN chmod 755 /primer_archivo.bash

USER nobody

ENTRYPOINT [ "/primer_archivo.bash" ]

La palabra FROM es para indicar que imagen utilizaremos, sino esta descargada la descargara del repositorio. LABEL, es solo la «etiqueta» que usamos como descripción; USER, es el usuario que ejecutará los comandos que le siguen. COPY y RUN serán las comandos que correrá nuestro usuario root.

El archivo primer_archivo.bash sera copiado al contenedor, al encontrarse en la misma ruta de Dockerfile no es necesario especificar una ruta diferente. RUN, actualiza el contenedor, instala curl y bash y otorga permisos al archivo copiado, es importante usar el gestor de paquetes correspondiente de la imagen sino mostrará error.

Construyamos la imagen.

[tusysadmin@local contenedores]$ ls
Dockerfile  primer_archivo.bash

[tusysadmin@local contenedores]$ docker build -t primer_imagen .
[+] Building 0.5s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                                                                      0.0s
 => => transferring dockerfile: 334B                                                                                                      0.0s
 => [internal] load .dockerignore                                                                                                         0.0s
 => => transferring context: 2B                                                                                                           0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                                                          0.4s
 => [internal] load build context                                                                                                         0.0s
 => => transferring context: 99B                                                                                                          0.0s
 => [1/5] FROM docker.io/library/ubuntu@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44fa6d77                           0.0s
 => => resolve docker.io/library/ubuntu@sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44fa6d77                           0.0s
 => CACHED [2/5] COPY ./primer_archivo.bash /                                                                                             0.0s
 => CACHED [3/5] RUN apt -y update                                                                                                        0.0s
 => CACHED [4/5] RUN apt -y install curl bash                                                                                             0.0s
 => CACHED [5/5] RUN chmod 755 /primer_archivo.bash                                                                                       0.0s
 => exporting to image                                                                                                                    0.0s
 => => exporting layers                                                                                                                   0.0s
 => => writing image sha256:ea88c13fe6d7ac18e8032717deaaf4ed18f049c4b887dcf21312c14874018151                                              0.0s
 => => naming to docker.io/library/primer_imagen

Esta es la forma mas simple de construir una imagen. Si tuvieramos un archivo con un nombre diferente a Dockerfile tendriamos que usar la opción -f seguida del nombre del archivo. Usamos un punto al final para especificar que usaremos el repositorio local.

[tusysadmin@local contenedores]$ docker images
REPOSITORY      TAG       IMAGE ID       CREATED             SIZE
primer_imagen   latest    ea88c13fe6d7   About an hour ago   116MB

[tusysadmin@local contenedores]$ docker run primer_imagen
Este es tu primer contenedor construido con Dockerfile
[tusysadmin@local contenedores]$

Como puede observarse la imagen ha sido creada y cuando se ejecuta hace lo único para lo cual ha sido construida, es decir ejecutar nuestro primer_archivo.bash.

Redes con docker

Al igual que en las maquinas virtuales, los contenedores pueden conectarse entre ellos y a través del host anfitrión para crear redes internas y/o publicar servicios.

Para ilustrar como funcionan los puertos, creemos un contender de ubuntu con los puertos 55678 y 55679 abiertos.

docker run --rm -ti -p 55678:55678 -p 55679:55679 --name echo-server ubuntu:14.04 bash

Este comando abre los mencionados puertos tanto de entrada como de salida, para ilustrar lo que estamos haciendo usemos el comando Netcat.

La terminal de la derecha es el contenedor que es quien inicia Netcat. Mientras tanto, lo escrito en la parte superior izquierda aparece en la terminal inferior por la conexión que se hace a través del contenedor.

Este escaneo es estático ya que establecimos los puertos de entrada y de salida, es posible establecer unicamente los de entrada y los de salida serán dinámicos.

[tusysadmin@local ~]$ docker run --rm -ti -p 55678 -p 55679 --name echo-server ubuntu:14.04 bash

Para saber los puertos utilizados usamos la opción port.

[tusysadmin@local ~]$ docker port echo-server
55679/tcp -> 0.0.0.0:49153
55679/tcp -> :::49153
55678/tcp -> 0.0.0.0:49154
55678/tcp -> :::49154

En este caso los puertos a los que tenemos que hacer la conexión son 49153 y 49154.

Para saber las redes con las que contamos.

[tusysadmin@local ~]$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2acddd4abdcd   bridge    bridge    local
8e60720c5590   host      host      local
b6c7de3fbd09   none      null      local

Estas tres redes son creadas al momento por default al momento de iniciar el servicio docker; sino se especifica lo contrario la red bridge es usada por todos los contenedores, host es para aislar contenedores a una red y none es para especificar que los contenedores no tienen red.

Crearemos un nueva red para conectar algunos contenedores.

[tusysadmin@local ~]$ docker network create taller
51ba550801cff8cf879630bb1925266d9ea45da375d6336c73f2b6e9a779926b

Creamos dos contenedores conectados a esa red.

[tusysadmin@local ~]$ docker run --rm -ti --network taller --name front ubuntu:14.04 bash
[tusysadmin@local ~]$ docker run --rm -ti --network taller --name back ubuntu:14.04 bash

Ping entre contenedores

Image 1 De 2

Como se observa en estas imágenes, existe una conexión entre contenedores solo con usar la misma red al momento de la declaración y es a través del nombre que pueden conectarse. Hagamos la cosas mas interesantes agregando un nueva red que solo pueda conectarse al back.

[tusysadmin@local ~]$ docker network create backsonly
a8f856b310666d071249bef328df3bbfbd2fa3e183923320cbb2425713f12720

[tusysadmin@local ~]$ docker network connect backsonly back

Crearemos un tercer contenedor que solo esté conectado a esta red el cual podrá hacer ping a back pero no a front.

Red separada

Image 1 De 1

El contenedor back por estar en ambas redes puede conectarse a ambos contenedores, pero entre ellos no es posible la conexión.

Pool iSCSI para KVM

KVM puede utilizar iSCSI como backend de almacenamiento, si se cuenta con una SAN (Storage Area Network) pueden asignarse LUN’s (Logical Unit Numbers) y presentarlas a las máquinas virtuales. El pool es creado en el almacenamiento pero libvirt no puede crearlo o eliminarlo.

Instalación Servidor iSCSI


Hostname: target.local
IP Address: 192.168.100.127

Comenzamos con la instalación.

]$ sudo yum install -y targetd targetcli
]$ sudo systemctl enable --now target

Habilitamos el servicio en el cortafuegos.

]$ sudo firewall-cmd --add-service=iscsi-target --permanent
]$ sudo firewall-cmd --reload
success

En este punto ya contamos con un lvm de 30 GB sin montar, en este caso /dev/vg1/lv1.

[tusysadmin@target ~]$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0          11:0    1 1024M  0 rom
vda         252:0    0    6G  0 disk
├─vda1      252:1    0    5G  0 part
│ ├─rl-root 253:0    0  4.4G  0 lvm  /
│ └─rl-swap 253:1    0  616M  0 lvm  [SWAP]
└─vda2      252:2    0    1G  0 part /boot
vdb         252:16   0   30G  0 disk
└─vdb1      252:17   0   30G  0 part
  └─vg1-lv1 253:2    0   30G  0 lvm

Lanzamos la utilidad targetcli.

[root@target ~]# targetcli
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> ls
o- / ............................................................... [...]
  o- backstores .................................................... [...]
  | o- block ........................................ [Storage Objects: 0]
  | o- fileio ....................................... [Storage Objects: 0]
  | o- pscsi ........................................ [Storage Objects: 0]
  | o- ramdisk ...................................... [Storage Objects: 0]
  o- iscsi .................................................. [Targets: 0]
  o- loopback ............................................... [Targets: 0]
/>

Crearemos un dispositivo de bloques, esto lo hacemos dentro de backstores/block.

/> backstores/block create vms_store /dev/vg1/lv1
Created block storage object vms_store using /dev/vg1/lv1.
/>

Creamos el IQN (iSCSI Qualified Name).

/> cd iscsi
/iscsi> create iqn.2022-05.com.target:vms
Created target iqn.2022-05.com.target:vms.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
/iscsi>

Creamos el LUN asociado al bloque vms_store.

/iscsi> cd iqn.2022-05.com.target:vms/tpg1
/iscsi/iqn.20...rget:vms/tpg1> luns/ create /backstores/block/vms_store
Created LUN 0.
/iscsi/iqn.20...rget:vms/tpg1>

Ahora creamos una ACL (Access Control List) en el que indicamos el IQN del cliente al que presentaremos la LUN.

/iscsi/iqn.20...rget:vms/tpg1> acls/ create iqn.2022-05.com.iniciator:vms
Created Node ACL for iqn.2022-05.com.iniciator:vms
Created mapped LUN 0.
/iscsi/iqn.20...rget:vms/tpg1>

Salimos de targetcli y verificamos que el puerto este abierto.

[tusysadmin@target ~]$ ss -an | grep 3260
tcp    LISTEN     0      256       *:3260                  *:*

Configurar iniciador

Ahora toca configurar el iniciador iSCSI en nuestro servidor de máquinas virtuales para posteriormente presentarlo a KVM.

[tusysadmin@localhost ~]$ sudo yum install iscsi-initiator-utils -y

Editamos el archivo initiatorname.iscsi

~]$ sudo vi /etc/iscsi/initiatorname.iscsi

En este archivo ponemos el nombre que anteriormente agregamos en la ACL.

InitiatorName=iqn.2022-05.com.iniciator:vms

Probamos la configuración.

[tusysadmin@localhost ~]$ sudo iscsiadm -m discovery -t st -p target.local
192.168.100.127:3260,1 iqn.2022-05.com.target:vms

Hacemos el login al target.

~]$ sudo iscsiadm --mode node --targetname iqn.2022-05.com.target:vms --portal target.local --login
Logging in to [iface: default, target: iqn.2022-05.com.target:vms, portal: 192.168.100.127,3260]
Login to [iface: default, target: iqn.2022-05.com.target:vms, portal: 192.168.100.127,3260] successful.

Crear el pool

Con la conexión establecida a nuestra servidor de maquina virtuales ya podemos crear el pool iSCSI y usarlo en nuestras maquinas virtuales. Creamos el archivo iscsipool.xml con el siguiente contenido.

<pool type='iscsi'>
    <name>iscsipool</name>
    <source>
        <host name='192.168.100.127'/>
        <device path='iqn.2022-05.com.target:vms'/>
    </source>
    <initiator>
	    <iqn name='iqn.2022-05.com.iniciator:vms' />
    </initiator>
    <target>
        <path>/dev/disk/by-path</path>
    </target>
</pool>

Básicamente es la información del target y del iniciador lista para ser agregada a KVM. Ahora definimos, iniciamos y auto iniciamos el pool.

[tusysadmin@localhost ~]$ sudo virsh pool-define --file iscsipool.xml
El grupo iscsipool ha sido definido desde iscsipool.xml

[tusysadmin@localhost ~]$ sudo virsh pool-start --pool iscsipool 
Se ha iniciado el grupo iscsipool

[tusysadmin@localhost ~]$ sudo virsh pool-autostart --pool iscsipool
El grupo iscsipool ha sido marcado como iniciable automáticamente

Listamos el pool la información de el mismo.

[tusysadmin@localhost ~]$ sudo virsh pool-info iscsipool
Nombre:         iscsipool
UUID:           80ba818f-14da-4c77-aee4-55f82dcefc34
Estado:         ejecutando
Persistente:    si
Autoinicio:     si
Capacidad:      30.00 GiB
Ubicación:      30.00 GiB
Disponible:     0.00 B

Con esto, el pool ya puede ser usado en KVM como otro pool para presentarse a las maquinas virtuales.

Web de alta disponibilidad con GlusterFS

En posts anteriores creamos un servidor web de alta disponibilidad usando Pacemaker y un servidor de archivos distribuidos con GlusterFS. En está ocasión uniremos un ambos proyectos para que tengan un mayor sentido.

En cada uno de los servidores involucrados usamos el siguiente archivo /etc/hosts:

192.168.100.117 www1.cluster www1
192.168.100.114 www2.cluster www2
192.168.100.122 nodo1.cluster nodo1
192.168.100.127 nodo2.cluster nodo2

Para hacerlos funcionar, instalamos el cliente glusterfs en los servidores web. Recordemos que estos servidores están funcionando en una distribución Rocky Linux por lo que hay que crear el repo /etc/yum.repos.d/CentOS-Gluster-9.repo.

[centos-gluster9]
name=CentOS-$releasever - Gluster 9
baseurl=https://dl.rockylinux.org/vault/centos/8.5.2111/storage/x86_64/gluster-9/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage

Para posteriormente instalar los paquetes que nos permitirán montar el servidor de archivos.

sudo yum install glusterfs glusterfs-libs glusterfs-client-xlators

En ambos servidores web montamos el sistema

~]$ sudo mount -t glusterfs nodo1.cluster:/volume_mirror /var/www/
[tusysadmin@www1 ~]$ df -h
S.ficheros                   Tamaño Usados  Disp Uso% Montado en
devtmpfs                       388M      0  388M   0% /dev
tmpfs                          405M    47M  358M  12% /dev/shm
tmpfs                          405M   5.7M  399M   2% /run
tmpfs                          405M      0  405M   0% /sys/fs/cgroup
/dev/mapper/rl-root            4.3G   2.2G  1.9G  54% /
/dev/vda2                      976M   274M  636M  31% /boot
tmpfs                           81M      0   81M   0% /run/user/0
nodo1.cluster:/volume_mirror    20G   238M   20G   2% /var/www

Para montar el sistema de archivos de forma automática al iniciar el servidor.

sudo echo "nodo1.cluster:/volume_mirror /var/www glusterfs defaults,_netdev 1 2" >> /etc/fstab

De esta forma contamos con alta disponibilidad a nivel sistema de archivos y servicios web ya que hemos se han integrado ambos proyectos.

Expresiones Regulares

Expresar mejor que lineas utilizar en los comandos para leer texto (grep y sed) es el principal uso de los expresiones regulares. Al dominarlas, podremos extender nuestro manejo de patrones o frases a buscar.

Si por ejemplo se buscan palabras que contengan la letra D en un archivo de texto.

[tusysadmin@localhost dict]$ grep d spanish | head -n 5
abad
abada
abadejo
abadenga
abadengo

Diferente sería mostrar las palabras que inician con esa letra, para esto usamos el acento circunflejo (^).

[tusysadmin@localhost dict]$ grep ^d spanish | tail -n 5
duunviral
duunvirato
duunviro
dux
duz

Si por el contrario, buscamos las palabras que terminen con la letra D usamos el símbolo de dólar ($).

[tusysadmin@localhost dict]$ grep d$ spanish | head -n 5
abad
absurdidad
accesibilidad
accidentalidad
aceptabilidad

Es posible usar los corchetes [ ] para indicar los caracteres que pueden aparecer dentro de una determinada posición.

[tusysadmin@localhost dict]$ grep ^d[aei]s[ae] spanish | tail -n 5
disertadora
disertante
disertar
diserto
disestesia

La salida del comando anterior muestra las palabras que inician con d seguido de una de las letras a, e o i; seguido de la letra s y por último una de las letras a o e.

Exclusiones y Rangos

Si lo que se busca es decir que caracteres no queremos imprimir usamos el ^ dentro de los corchetes.

[tusysadmin@localhost dict]$  grep ^m[^aei]s[ae] spanish | tail -n5
muselina
museo
museografía
musequí
muserola

Dentro de los corchetes es posible aceptar rangos para indicar todos los valores intermedios entre valor inicial y final. Esto sustituye el tener que escribir varias letras o números.

[tusysadmin@localhost dict]$  grep ^c[l-t]s[m-z].$ spanish
cospe
costa
coste
costo

Podemos negar el contenido de los corchetes usando en circunflejo.

[tusysadmin@localhost dict]$  grep ^c[^l-t]s[m-z].$ spanish
casón
caspa
casta
casto
cesta
cesto
cisma
cisne

Expresiones Extendidas

Se trata del uso de grep con la opción -E, en Unix y en algunas distribuciones puede usarse el comando egrep pero es poco usada.

Buscar palabras que tengan letras de un determinado rango y número.

tusysadmin@localhost dict]$ grep -E '^[g-p]{8}$' spanish 
hipólogo
homólogo
homónimo
mogollón
monólogo
pimpollo
piojillo
piopollo
polígono

Las palabras mostradas tienen 8 letras y además están entre g y p. He fijado el número de letras pero pueden ser rangos; por ejemplo, entre 4 y 8.

[tusysadmin@localhost dict]$ grep -E '^[g-p]{4,8}$' spanish | head -n 5
gilí
gnomo
gnomon
gong
gongo

Hasta 8 letras.

[tusysadmin@localhost dict]$ grep -E '^[g-p]{,8}$' spanish | tail -n 5
pomo
pomol
pompo
pompón
pongo

Al menos 5 letras.

[tusysadmin@localhost dict]$ grep -E '^[g-p]{5,}$' spanish | head -n 5
gnomo
gnomon
gongo
himno
hinojo

Es posible el uso de expresiones extendidas para buscar todas las palabras con cierto número de letras; por ejemplo, 7.

Mostrar dos expresiones regulares.

[tusysadmin@localhost dict]$ grep -E '^a.*t$|^e.*z$' spanish 
accésit
acimut
alacet
algunt
eficaz
electriz
escasez
estupidez

Es posible la agrupación de expresiones regulares usando paréntesis o para afectar un determinado carácter en especial, ejemplo.

[tusysadmin@localhost dict]$ grep -E '(c[aeiou]){2}' spanish | head
abdicación
acacia
acacianos
acecido
acecinador

De igual forma que en ejemplos anteriores, el numero puede ser fijo o manejar mínimos y máximos. Hasta aquí el post del día de hoy, cualquier duda la pueden dejar en los comentarios.

Sustitución de Caracteres en Linux

Cuando tenemos archivos de texto y queremos dar formato simplemente abrimos el archivo en cuestión con nuestro editor de texto preferido (nano o vim) y modificamos dicho archivo. Lamentablemente, no siempre es posible hacer todo con editores de texto, para esos casos existen comandos que permiten la modificación de texto de una forma practica y sencilla.

Antes de empezar a tirar comandos es necesario saber que existen clases de caracteres.

[:alnum:] : Letras y Dígitos
[:alpha:] : Letras
[:blank:] : Espacios en Blanco
[:cntrl:] : Caracteres de control
[:digit:] : Dígitos
[:graph:] : Caracteres impresos sin incluir espacios
[:lower:] : Letras minúsculas
[:print:] : Caracteres impresos incluidos espacios
[:punct:] : Signos de puntuación
[:space:] : Espacios en blanco verticales y horizontales 
[:upper:] : Letras mayúsculas
[:xdigit:] : Dígitos Hexadecimales

Tomando como ejemplo el siguiente archivo de texto.

[tusysadmin@localhost ~]$ cat saludo.txt
Bienvenidos a Avenida Siempre Viva 742

Sustituir todos los dígitos por X.

[tusysadmin@localhost ~]$ tr [:digit:] X < saludo.txt 
Bienvenidos a Avenida Siempre Viva XXX

Sustituir las letras por el número 0.

[tusysadmin@localhost ~]$ tr [:alpha:] 0 < saludo.txt 
00000000000 0 0000000 0000000 0000 742

Sustituir los espacios en blanco por un –

[tusysadmin@localhost ~]$ tr [:blank:] - < saludo.txt 
Bienvenidos-a-Avenida-Siempre-Viva-742

Sustituir minúsculas por mayúsculas.

[tusysadmin@localhost ~]$ tr [:lower:] [:upper:]  < saludo.txt 
BIENVENIDOS A AVENIDA SIEMPRE VIVA 742

Si quisiéramos sustituir o eliminar determinadas palabras y/o lineas de un archivo como el siguiente, nos podemos apoyar con el comando sed.

[tusysadmin@localhost ~]$ cat -n navegadores.txt 
     1	Los navegadores Web facilitaron el uso de Internet,
     2	Sin ellos seguiríamos usando lineas de comandos 
     3	para conectarnos a los servicios que necesitamos.
     4	
     5	Los más conocidos son Edge, Mozilla Firefox,
     6	Opera, Safari y Google Chrome. Sin embargo, 
     7	son el resultado de la varias adaptaciones, cambios
     8	y evoluciones.
     9	
    10	El primer navegador fue WorlWideWeb pero solo 
    11	funcionaba con Next. El segundo fue Mosaic del 
    12	cual Mozilla tomó código para su desarrollo, pero 
    13	uno de los más importantes y que fue el boom de 
    14	los navegadores fue NetScape.
    15	
    16	NetScape tuvo tanto éxito que motivó la creación
    17	de Internet Explorer por parte de Microsoft. Al final,
    18	NetScape perdió la llamada guerra de los navegadores
    19	contra Internet Explorer.
    20	
    21	Hoy en día Internet Explorer se encuentra al borde de
    22	ser descontinuado para dar paso a Edge. Veremos en 
    23	el futuro que navegador logra sobrevivir.

Mostrar el último párrafo (lineas 21-23) indicando la omisión de las lineas 1-20.

[tusysadmin@localhost ~]$ cat -n navegadores.txt | sed -e '1,20d' 
    21	Hoy en día Internet Explorer se encuentra al borde de
    22	ser descontinuado para dar paso a Edge. Veremos en 
    23	el futuro que navegador logra sobrevivir.

Imprimir ciertas lineas usando la opción -p.

[tusysadmin@localhost ~]$ cat -n navegadores.txt | sed -n -e '1,3p' 
     1	Los navegadores Web facilitaron el uso de Internet,
     2	Sin ellos seguiríamos usando lineas de comandos 
     3	para conectarnos a los servicios que necesitamos.

Omitir los las lineas en blanco.

[tusysadmin@localhost ~]$  sed '/^$/d' navegadores.txt

Sustituir las líneas en blanco.

[tusysadmin@localhost ~]$  sed -e '/^$/c\#Linea en blanco' navegadores.txt
Los navegadores Web facilitaron el uso de Internet,
Sin ellos seguiríamos usando lineas de comandos 
para conectarnos a los servicios que necesitamos.
#Linea en blanco 
Los más conocidos son Edge, Mozilla Firefox,
Opera, Safari y Google Chrome. Sin embargo, 
son el resultado de la varias adaptaciones, cambios
y evoluciones.
#Linea en blanco 
El primer navegador fue WorlWideWeb pero solo 
funcionaba con Next. El segundo fue Mosaic del 
cual Mozilla tomó código para su desarrollo, pero 
uno de los más importantes y que fue el boom de 
los navegadores fue NetScape.
#Linea en blanco 
NetScape tuvo tanto éxito que motivó la creación
de Internet Explorer por parte de Microsoft. Al final,
NetScape perdió la llamada guerra de los navegadores
contra Internet Explorer.
#Linea en blanco 
Hoy en día Internet Explorer se encuentra al borde de
ser descontinuado para dar paso a Edge. Veremos en 
el futuro que navegador logra sobrevivir.

Este comando sustituye las lineas en donde encuentra la coincidencia, el problema es que sustituye toda la linea, si en lugar de buscar lineas en blanco hubiera buscado las palabras Internet Explorer, entonces pasaría algo como lo siguiente.

~]$ sed -e '/Internet Explorer/c\Explorer was Here' navegadores.txt
Los navegadores Web facilitaron el uso de Internet,
Sin ellos seguiríamos usando lineas de comandos 
para conectarnos a los servicios que necesitamos.

Los más conocidos son Edge, Mozilla Firefox,
Opera, Safari y Google Chrome. Sin embargo, 
son el resultado de la varias adaptaciones, cambios
y evoluciones.

El primer navegador fue WorlWideWeb pero solo 
funcionaba con Next. El segundo fue Mosaic del 
cual Mozilla tomó código para su desarrollo, pero 
uno de los más importantes y que fue el boom de 
los navegadores fue NetScape.

NetScape tuvo tanto éxito que motivó la creación
Explorer was Here
NetScape perdió la llamada guerra de los navegadores
Explorer was Here

Explorer was Here
ser descontinuado para dar paso a Edge. Veremos en 
el futuro que navegador logra sobrevivir.

Sustituir exclusivamente una palabra o palabras sin quitar toda la linea.

~]$ sed -e 's/Internet Explorer/Explorer Lento/g' navegadores.txt 
Los navegadores Web facilitaron el uso de Internet,
Sin ellos seguiríamos usando lineas de comandos 
para conectarnos a los servicios que necesitamos.

Los más conocidos son Edge, Mozilla Firefox,
Opera, Safari y Google Chrome. Sin embargo, 
son el resultado de la varias adaptaciones, cambios
y evoluciones.

El primer navegador fue WorlWideWeb pero solo 
funcionaba con Next. El segundo fue Mosaic del 
cual Mozilla tomó código para su desarrollo, pero 
uno de los más importantes y que fue el boom de 
los navegadores fue NetScape.

NetScape tuvo tanto éxito que motivó la creación
de Explorer Lento por parte de Microsoft. Al final,
NetScape perdió la llamada guerra de los navegadores
contra Explorer Lento.

Hoy en día Explorer Lento se encuentra al borde de
ser descontinuado para dar paso a Edge. Veremos en 
el futuro que navegador logra sobrevivir.

El uso de sed se extiende a las hojas de calculo, ya que es posible manejarlas como cualquier archivo de texto. Para este ejemplo generé un archivo en http://generatedata.com/ al que nombré random.csv.

[tusysadmin@localhost ~]$ cat -n random.csv 
     1	name,phone,email,country
     2	Branden Bowers,(143) 413-5107,semper.pretium.neque@hotmail.org,Sweden
     3	Sheila Reeves,(161) 474-5087,libero.et.tristique@hotmail.com,Italy
     4	Quentin Parsons,(901) 364-1366,maecenas@hotmail.couk,United States
     5	Eleanor Villarreal,(411) 615-1484,dolor@yahoo.com,Australia
     6	Denton Potter,(415) 973-8034,tempus@aol.org,Canada
     7	Ciara Levine,1-872-792-7213,interdum.sed@outlook.org,United Kingdom
     8	Brennan Ferguson,1-811-855-4917,augue.scelerisque.mollis@aol.couk,Ireland
     9	Hedwig Reese,1-626-734-3287,eu.dolor@yahoo.org,Chile
    10	Dominic Tran,1-453-421-4797,a@hotmail.couk,Turkey
    11	Zeus Mccormick,(771) 383-8618,et.netus.et@google.net,Ireland

Si eliminamos todos los correos con el dominio @aol debido ya que el dominio ha dejado de existir.

[tusysadmin@localhost ~]$ cat -n random.csv | grep @aol
     6	Denton Potter,(415) 973-8034,tempus@aol.org,Canada
     8	Brennan Ferguson,1-811-855-4917,augue.scelerisque.mollis@aol.couk,Ireland

De igual forma, se nos pide que modifiquemos el domino hotmail por msn.

[tusysadmin@localhost ~]$ cat -n random.csv | grep hotmail
     2	Branden Bowers,(143) 413-5107,semper.pretium.neque@hotmail.org,Sweden
     3	Sheila Reeves,(161) 474-5087,libero.et.tristique@hotmail.com,Italy
     4	Quentin Parsons,(901) 364-1366,maecenas@hotmail.couk,United States
    10	Dominic Tran,1-453-421-4797,a@hotmail.couk,Turkey

Ambas cosas pueden hacerse en una sola linea de código.

~]$ sed -e '/@aol/d' -e 's/hotmail/msn/g' random.csv 
name,phone,email,country
Branden Bowers,(143) 413-5107,semper.pretium.neque@msn.org,Sweden
Sheila Reeves,(161) 474-5087,libero.et.tristique@msn.com,Italy
Quentin Parsons,(901) 364-1366,maecenas@msn.couk,United States
Eleanor Villarreal,(411) 615-1484,dolor@yahoo.com,Australia
Ciara Levine,1-872-792-7213,interdum.sed@outlook.org,United Kingdom
Hedwig Reese,1-626-734-3287,eu.dolor@yahoo.org,Chile
Dominic Tran,1-453-421-4797,a@msn.couk,Turkey
Zeus Mccormick,(771) 383-8618,et.netus.et@google.net,Ireland

Con este simple comando borramos todas las lineas que tengan un correo con el dominio @aol y al mismo tiempo reemplazamos el dominio hotmail por msn. Para guardar los cambios en el archivo usamos la opción -i.

~]$ sed -i -e '/@aol/d' -e 's/hotmail/msn/g' random.csv 
[tusysadmin@localhost ~]$ cat -n random.csv 
     1	name,phone,email,country
     2	Branden Bowers,(143) 413-5107,semper.pretium.neque@msn.org,Sweden
     3	Sheila Reeves,(161) 474-5087,libero.et.tristique@msn.com,Italy
     4	Quentin Parsons,(901) 364-1366,maecenas@msn.couk,United States
     5	Eleanor Villarreal,(411) 615-1484,dolor@yahoo.com,Australia
     6	Ciara Levine,1-872-792-7213,interdum.sed@outlook.org,United Kingdom
     7	Hedwig Reese,1-626-734-3287,eu.dolor@yahoo.org,Chile
     8	Dominic Tran,1-453-421-4797,a@msn.couk,Turkey
     9	Zeus Mccormick,(771) 383-8618,et.netus.et@google.net,Ireland

Con esto llegamos al final del post cualquier duda puedes dejarla en la caja de comentarios.

Tuberías y redirecciones

La salida de los comandos que ponemos en nuestra terminal pueden ser redirigidos a un archivo o ser reutilizados por otro comando. Por ejemplo, imprimiremos en pantalla el famoso Hola mundo

[tusysadmin@localhost ~]$ echo "Hola mundo"
Hola mundo

Por otro lado, si quisiéramos mandar este mensaje a un archivo lo haríamos así:

[tusysadmin@localhost ~]$ echo "Hola mundo" > hola
[tusysadmin@localhost ~]$ cat hola 
Hola mundo

El signo > mandará la salida del comando a un archivo y sobrescribirá el contenido que tenga dicho archivo. Si lo que se quiere es conservar el contenido previo entonces usamos el doble >>.

[tusysadmin@localhost ~]$ echo "Hola mundo" >> hola
[tusysadmin@localhost ~]$ echo "Hola mundo" >> hola
[tusysadmin@localhost ~]$ echo "Hola mundo" >> hola
[tusysadmin@localhost ~]$ cat hola 
Hola mundo
Hola mundo
Hola mundo
Hola mundo
[tusysadmin@localhost ~]$ 

Las redirecciones pueden ser usadas para guardar mensajes de error usando >2 o >>2

[tusysadmin@localhost ~]$ yum install nginx 2> error.log
[tusysadmin@localhost ~]$ cat error.log 
Error: Este comando debe ejecutarse con privilegios de superusuario

Para conservar todos los mensajes de salida sin que estos se impriman en la pantalla usamos &> o &>> para evitar la sobrescritura.

Las redirecciones nos ayudan a generar archivos de logs para detectar problemas en instalaciones o ejecuciones de algún script de bash. De igual forma, pudiéramos no querer conservar ni imprimir la salida de un comando, si fuera el caso simplemente desechamos esta información mandándola a /dev/null.

[tusysadmin@localhost ~]$ du -sh /* 2> /dev/null 
0        /bin
193M     /boot
0        /dev
30M      /etc
25M      /home
0        /lib
0        /lib64
16K      /lost+found
4.0K     /media
4.0K     /mnt
8.0K     /opt
0        /proc
4.0K     /root
1.7M     /run
0        /sbin
4.0K     /srv
0        /sys
96K      /tmp
8.2G     /usr
6.0G     /var

De esta manera tenemos una impresión en pantalla limpia y sin conservar errores.

Tuberías

Las tuberías nos permite utilizar la salida de texto de un comando como entrada de otro. De esta forma podemos simplificar la salida deseada. Ejemplo, el siguiente comando muestra todos los usuarios que inician con la letra t.

[tusysadmin@localhost ~]$ grep ^t /etc/passwd 
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
tusysadmin:x:1001:1001::/home/tusysadmin:/bin/bash

Como puede observarse, imprime información que no necesitamos si quisiéramos crear una lista. Para tomar este comando lo conectamos con «|»

[tusysadmin@localhost ~]$ grep ^t /etc/passwd | cut -d ":" -f1
tss
tcpdump
tusysadmin

De este modo corté todo lo que aparece antes del signo : quedando en una sola columna. Si necesitamos saber el uso en disco de los directorios de nuestro sistema ordenado de mayor a menor.

[tusysadmin@localhost ~]$ du -sh /* 2> /dev/null | sort -hr
8.2G    /usr
6.0G    /var
193M    /boot
30M     /etc
25M     /home
1.7M    /run
156K    /tmp
16K     /lost+found
8.0K    /opt
4.0K    /srv
4.0K    /root
4.0K    /mnt
4.0K    /media
0       /sys
0       /sbin
0       /proc
0       /lib64
0       /lib
0       /dev
0       /bin

Hojas de cálculo con comandos

Es posible manejar hojas de calculo con la terminal; para esto, el archivo debe ser guardado en el formato CSV (Valores Separados por Comas). Tomando como ejemplo el siguiente archivo.

Seguramente habrás notado la falta de acentos en el nombre de los autores y libros así como la mezcla de mayúsculas y minúsculas. Lo primero es por qué en bash no se aceptan acentos ni el uso de la letra Ñ y lo segundo es parte de lo que intentaremos arreglar desde nuestra terminal.

Un archivo CSV se ve así desde en nuestra terminal, intencionalmente he omitido la primer linea.

tusysadmin@localhost ~]$ cat autores.csv 
Juan Rulfo,El llano en llamas,1953
JUAN RULFO,PEDRO PARAMO,1955
GABRIEL GARCIA Marquez,La mala hora,1962
MARIO BENEDETTI,La tregua,1960
MARIO Benedetti,LA BORRA DEL CAFE,1992
Octavio Paz,Piedra del sol,1957
GABRIEL GARCIA Marquez,La hojarasca,1955
GABRIEL Garcia MARQUEZ,El coronel no tiene quien le escriba,1961
OCTAVIO PAZ,SALAMANDRA,1962
GABRIEL GARCIA MARQUEZ,El amor en los tiempos del colera,1985
GABRIEL GARCIA MARQUEZ,Del amor y otros demonios,1994
OCTAVIO PAZ,LUNA SILVESTRE,1933

Cambiar minúsculas por mayúsculas.

tusysadmin@localhost:~$ cat autores.csv | tr \[:lower:] \[:upper:]
JUAN RULFO,EL LLANO EN LLAMAS,1953
JUAN RULFO,PEDRO PARAMO,1955
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
MARIO BENEDETTI,LA TREGUA,1960
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
OCTAVIO PAZ,PIEDRA DEL SOL,1957
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
OCTAVIO PAZ,SALAMANDRA,1962
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
OCTAVIO PAZ,LUNA SILVESTRE,1933

El comando tr significa literalmente traduce. Cambia, elimina o traduce una entrada en una salida.

tr [OPTION]... SET1 [SET2]

En el caso de nuestro ejemplo, cambiara todas las letras minúsculas [:lower:] por mayúsculas [:upper:]. Usamos el carácter > para escribir la salida del comando en un nuevo archivo.

@localhost:~$ cat autores.csv | tr \[:lower:] \[:upper:] > escritores.csv
tusysadmin@localhost:~$ cat escritores.csv
JUAN RULFO,EL LLANO EN LLAMAS,1953
JUAN RULFO,PEDRO PARAMO,1955
GABRIEL GARCIA MARQUEZ ,LA MALA HORA,1962
MARIO BENEDETTI,LA TREGUA,1960
MARIO BENEDETTI ,LA BORRA DEL CAFE,1992
OCTAVIO PAZ,PIEDRA DEL SOL,1957
GABRIEL GARCIA MARQUEZ ,LA HOJARASCA,1955
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
OCTAVIO PAZ,SALAMANDRA,1962
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
OCTAVIO PAZ,LUNA SILVESTRE,1933

Ordenar csv

Orden alfabéticamente
tusysadmin@localhost:~$ sort escritores.csv
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
JUAN RULFO,EL LLANO EN LLAMAS,1953
JUAN RULFO,PEDRO PARAMO,1955
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
MARIO BENEDETTI,LA TREGUA,1960
OCTAVIO PAZ,LUNA SILVESTRE,1933
OCTAVIO PAZ,PIEDRA DEL SOL,1957
OCTAVIO PAZ,SALAMANDRA,1962

En este caso se toma como referencia la primer y segunda columna, no se continua con la tercera por tratarse de números y no se le ha indicado a sort que ordene valores numéricos. Para tomar como referencia el segunda columna.

tusysadmin@localhost:~$ sort -k 2,2 -t \, escritores.csv
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
JUAN RULFO,EL LLANO EN LLAMAS,1953
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
MARIO BENEDETTI,LA TREGUA,1960
OCTAVIO PAZ,LUNA SILVESTRE,1933
JUAN RULFO,PEDRO PARAMO,1955
OCTAVIO PAZ,PIEDRA DEL SOL,1957
OCTAVIO PAZ,SALAMANDRA,1962

Orden numérico
tusysadmin@localhost:~$ sort -n -k 3 -t \, escritores.csv
OCTAVIO PAZ,LUNA SILVESTRE,1933
JUAN RULFO,EL LLANO EN LLAMAS,1953
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
JUAN RULFO,PEDRO PARAMO,1955
OCTAVIO PAZ,PIEDRA DEL SOL,1957
MARIO BENEDETTI,LA TREGUA,1960
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
OCTAVIO PAZ,SALAMANDRA,1962
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994

La opción -n es usada para ordenar con valores numéricos, -k indica el numero de la columna usada como referencia; en este caso la tercer columna y finalmente -t para el campo delimitador.

Ahora ordenaremos por autor y estos a su vez por fecha de publicación.

tusysadmin@localhost:~$ sort -k1,1 -k3n,3 -t \, escritores.csv
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
JUAN RULFO,EL LLANO EN LLAMAS,1953
JUAN RULFO,PEDRO PARAMO,1955
MARIO BENEDETTI,LA TREGUA,1960
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
OCTAVIO PAZ,LUNA SILVESTRE,1933
OCTAVIO PAZ,PIEDRA DEL SOL,1957
OCTAVIO PAZ,SALAMANDRA,1962

En caso de que quisiéramos la más reciente publicación usamos la opción -r.

tusysadmin@localhost:~$ sort -k1,1 -k3r,3 -t \, escritores.csv
GABRIEL GARCIA MARQUEZ,DEL AMOR Y OTROS DEMONIOS,1994
GABRIEL GARCIA MARQUEZ,EL AMOR EN LOS TIEMPOS DEL COLERA,1985
GABRIEL GARCIA MARQUEZ,LA MALA HORA,1962
GABRIEL GARCIA MARQUEZ,EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
GABRIEL GARCIA MARQUEZ,LA HOJARASCA,1955
JUAN RULFO,PEDRO PARAMO,1955
JUAN RULFO,EL LLANO EN LLAMAS,1953
MARIO BENEDETTI,LA BORRA DEL CAFE,1992
MARIO BENEDETTI,LA TREGUA,1960
OCTAVIO PAZ,SALAMANDRA,1962
OCTAVIO PAZ,PIEDRA DEL SOL,1957
OCTAVIO PAZ,LUNA SILVESTRE,1933

Manejar Columnas

Si buscamos mostrar las columnas del titulo y del año de publicación.

tusysadmin@localhost:~$ cut -f 2,3 -d \, escritores.csv
EL LLANO EN LLAMAS,1953
PEDRO PARAMO,1955
LA MALA HORA,1962
LA TREGUA,1960
LA BORRA DEL CAFE,1992
PIEDRA DEL SOL,1957
LA HOJARASCA,1955
EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
SALAMANDRA,1962
EL AMOR EN LOS TIEMPOS DEL COLERA,1985
DEL AMOR Y OTROS DEMONIOS,1994
LUNA SILVESTRE,1933

La opción -d es el delimitador, en este caso la coma, con -f establecemos las columnas que se imprimirán. Si queremos que se ordenen por año de publicación podemos redirigir con un sort.

@localhost:~$ cut -f 2,3 -d \, escritores.csv | sort -k2n,2 -t \,
LUNA SILVESTRE,1933
EL LLANO EN LLAMAS,1953
LA HOJARASCA,1955
PEDRO PARAMO,1955
PIEDRA DEL SOL,1957
LA TREGUA,1960
EL CORONEL NO TIENE QUIEN LE ESCRIBA,1961
LA MALA HORA,1962
SALAMANDRA,1962
EL AMOR EN LOS TIEMPOS DEL COLERA,1985
LA BORRA DEL CAFE,1992
DEL AMOR Y OTROS DEMONIOS,1994

Si quisiéramos saber el numero de obras de cada autor en orden alfabético.

tusysadmin@localhost:~$ cut -f 1 -d \, escritores.csv | sort | uniq -c
      5 GABRIEL GARCIA MARQUEZ
      2 JUAN RULFO
      2 MARIO BENEDETTI
      3 OCTAVIO PAZ

« Entradas anteriores

© 2025

Tema por Anders NorenArriba ↑