Facebook Twitter Google Digg Reddit Email Imprimir
Martes 16 de octubre de 2018
Santoral:
Eduvigis
Otros:
Día Mundial de la Alimentación
Día del Profesor
Semana:
42
Día año:
289/365 (79%)
U.F.:
27389.73
IPC:
0,3
Dolar:
683,7
Euro:
791,5
Bitcoin:
U$ 6447.3769322344
mindicador.cl
Time4VPS.EU - VPS hosting in Europe

xargs: Ejecutar un comando con argumentos desde un archivo

El compañero ideal del comando find

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
...
Escrito por: Luis Hernán de la Barra, 14/07/2016

Generado por Sistema y almacenado en cache

Wyzer
Luis Hernán de la Barra
E-Mail:ldelabar@wyzer.cl
Web:www.wyzer.cl