xargs: Ejecutar un comando con argumentos desde un archivo
Introducción
Existen casos en que debemos ejecutar un comando repetidamente sobre los datos que nos entregan en un archivo, por ejemplo, bloquear servicio a una lista de usuarios. Probablemente podemos recurrir a un script, pero existe el comando xargs que puede ser de gran ayuda.
Otro caso muy común es borrar archivos logs o temporales que tengan más de 30 días, aunque basta hacer un find . -mtime +30 -exec rm {} \;
, puede ser muy ineficiente, dado que debe generar un nuevo proceso por cada archivo que borra, y donde xargs nos puede ayudar agrupando varios archivos en cada ejecución de rm
.
Descripción
El comando xargs
opera como filtro, leyendo la lista de los argumentos para construir el comando desde la entrada standard, por lo que en general se ejecuta por medio de un pipe como:
cat clientesnopago.txt | xargs -n 1 bloquearcliente.sh
find /var/app/temporales -mtime +1 | xargs -n 10 rm
find /var/app/logs -mtime +3 | xargs -n 5 gzip -v
Opciones
Contamos con algunas opciones que nos permiten controlar o depurar la acción a realizar, revicemos las más simples:
- --version
- Muestra la versión y sale
- --verbose, -t
- Permite visualizar por la salida de errores los comandos que se ejecutan
- --interactive, -p
- Nos pide una confirmación antes de ejecutar cada comando
- --max-lines[=max-lines], -l[max-lines]
- Utiliza hasta max-lines líneas del archivo de entrada para generar el comando
- --max-args=max-args, -n max-args
- Utiliza hasta max-args argumentos del archivo de entrada para generar el comando, cada línea del archivo de entrada puede tener m&uacte;ltiples argumentos al separarlos por espacios
- --max-chars=max-chars, -s max-chars
- Utiliza hasta un máximo de max-chars caracteres para la construcción del comando, inicialmente se asume del órden de 20.000 caracteres
- --no-run-if-empty, -r
- Si no hay datos de entrada, se omite la ejecución del comando. Al no dar ésta opción se ejecuta a lo menos una vez
- --exit, -x
- Acaba si se sobrepasa el tamaño dado
- --replace[=replace-str], -i[replace-str]
- Define el string replace-str para ser reemplazado por el dato obtenido de la entrada, por defecto se asume {} como patrón, implica opción
-l1
. Es necesario al utilizar comandos donde el parámetro a incluir no se encuentra al final - --max-procs=max-procs, -P max-procs
- Ejecuta hasta max-procs en paralelo, generalmente se utiliza en conjunto de la opción '-n' para forzar múltiples comando. Con el valor "0" (Cero) se generan tantos procesos como sean necesarios. Use con precaución dado que puede saturar el equipo al generar muchos proceso, probablemente no exceda la cantidad de CPUs del equipo.
Ejemplos
Comprimir múltiples archivos de log
Se tiene el directorio /var/app/log con unos 300 archivos de logs de gran tamaño que requerimos comprimir rápidamente aquellos con más de 3 días. Nuestro equipo cuenta con 4 Cores de CPU, de los que podemos utilizar 3. Utilizaremos gzip para realizar la compresión, daremos 5 archivos en cada comando:
find /var/app/log -mtime +3 | xargs -n 5 -P 3 gzip -v
Cambiar cuota 10MB de una lista de usuarios
Suponiendo que tenemos un servicio sujeto a una cuota, nos entregan una lista de usuarios en el archivo userid.txt, con un identificador por línea, a los cuales debemos cambiar dicha cuota a 10MB, para ello contamos con el comando modificacuota.sh, pero debemos especificar dicho identificador como
id=identificador, y luego la cuota como 10MB. La magia se crea con el comando:
cat userid.txt | xargs -iUSERID --verbose ./modificacuota.sh id=USERID 10M
./modificacuota.sh id=1690657759 10M ** Usuario id=1690657759 modifica cuota a 10M ./modificacuota.sh id=2098009460 10M ** Usuario id=2098009460 modifica cuota a 10M ./modificacuota.sh id=113798706 10M ** Usuario id=113798706 modifica cuota a 10M ./modificacuota.sh id=1416112042 10M ** Usuario id=1416112042 modifica cuota a 10M ./modificacuota.sh id=191501542 10M ** Usuario id=191501542 modifica cuota a 10M ./modificacuota.sh id=885404729 10M ** Usuario id=885404729 modifica cuota a 10M ...
Modificar cuota de usuario al valor dado
Similar al caso anterior, pero ésta vez nos dicen cual es la cuota a asignar. Para simplificar la tarea, solicitamos el archivo de entrada con la forma:
id=876556484 10MB id=969044334 30MB id=418263791 30MB id=1851549969 30MB id=205419609 10MB id=845094155 20MB id=517431767 20MB id=1307261167 20MB id=142359855 30MB id=119037694 20MB id=191712534 10MB ...
Con ello, procedemos a procesar simplemente con el comando:
cat nuevacuota.txt| xargs -l1 --verbose ./modificacuota.sh
./modificacuota.sh id=876556484 10MB ** Usuario id=876556484 modifica cuota a 10MB ./modificacuota.sh id=969044334 30MB ** Usuario id=969044334 modifica cuota a 30MB ./modificacuota.sh id=418263791 30MB ** Usuario id=418263791 modifica cuota a 30MB ./modificacuota.sh id=1851549969 30MB ** Usuario id=1851549969 modifica cuota a 30MB ./modificacuota.sh id=205419609 10MB ** Usuario id=205419609 modifica cuota a 10MB ./modificacuota.sh id=845094155 20MB ** Usuario id=845094155 modifica cuota a 20MB ./modificacuota.sh id=517431767 20MB ** Usuario id=517431767 modifica cuota a 20MB ./modificacuota.sh id=1307261167 20MB ** Usuario id=1307261167 modifica cuota a 20MB ./modificacuota.sh id=142359855 30MB ** Usuario id=142359855 modifica cuota a 30MB ...
Generado por Sistema y almacenado en cache
Wyzer Luis Hernán de la Barra |
|
Teléfono: | +56995451689 |
WhatsApp: | +56995451689 |
E-Mail: | info@wyzer.cl |
Web: | www.wyzer.cl |