xargs (abreviatura de "extended arguments") [ 1 ] es un comando en Unix y la mayoría de los sistemas operativos tipo Unix que se utiliza para construir y ejecutar comandos desde la entrada estándar . Convierte la entrada de la entrada estándar en argumentos para un comando.
Algunos comandos, como grepy , awkpueden aceptar argumentos de línea de comandos o la entrada estándar. Sin embargo, otros, como cpy , echosolo aceptan argumentos, por lo que xargs es necesario.
Existe una versión adaptada de una versión anterior de GNU xargs para Microsoft Windows, que forma parte de la colección UnxUtils de adaptaciones nativas para Win32 de utilidades comunes de tipo GNU Unix. [ 2 ] Una reescritura completa llamada wargs forma parte del proyecto de código abierto TextTools [ 3 ] . El comando xargs también se ha adaptado al sistema operativo IBM i . [ 4 ]
Ejemplos
Un caso de uso del comando xargs es eliminar una lista de archivos usando el comando rm . Los sistemas POSIX tienen un ARG_MAX para la longitud total máxima de la línea de comandos, [ 5 ] [ 6 ] por lo que el comando puede fallar con un mensaje de error de "Lista de argumentos demasiado larga" (lo que significa que se superó el límite de la llamada al sistema exec en la longitud de una línea de comandos): o . (Esta última invocación es incorrecta, ya que puede expandir comodines en la salida).rm/path/*rm$(find/path-typef)
Esto se puede reescribir utilizando el xargscomando para dividir la lista de argumentos en sublistas lo suficientemente pequeñas como para ser aceptables:
$ find /path -type f -print | xargs rm En el ejemplo anterior, la findutilidad introduce xargsuna larga lista de nombres de archivos. xargsLuego, divide esta lista en sublistas y llama a la función rmuna vez por cada sublista.
Algunas implementaciones de xargs también permiten paralelizar operaciones con el -P maxprocsargumento que especifica cuántos procesos paralelos se deben usar para ejecutar los comandos sobre las listas de argumentos de entrada. Sin embargo, es posible que los flujos de salida no estén sincronizados. Esto se puede solucionar utilizando un --output fileargumento cuando sea posible y combinando los resultados después del procesamiento. El siguiente ejemplo pone en cola 24 procesos y espera a que cada uno finalice antes de iniciar otro.
$ find /path -name '*.foo' | xargs -P 24 -I '{}' /cpu/bound/process '{}' -o '{}' .out xargs suele cubrir la misma funcionalidad que la función de sustitución de comandos de muchos shells , denotada por la notación de comillas invertidas ( `...`o $(...)). xargs también es un buen complemento para comandos que generan largas listas de archivos como find, locatey grep, pero solo si se usa -0(o equivalentemente --null), ya que xargssin -0maneja mal los nombres de archivo que contienen ', "y espacios. GNU Parallel es una herramienta similar que ofrece mejor compatibilidad con find , locate y grep cuando los nombres de archivo pueden contener ', "y espacios (el salto de línea aún requiere -0).
Ubicación de los argumentos
-Iopción: argumento único
El comando xargs ofrece opciones para insertar los argumentos listados en una posición distinta al final de la línea de comandos. La -Iopción de xargs toma una cadena que se reemplazará con la entrada proporcionada antes de que se ejecute el comando. Una opción común es %.
$ mkdir ~/backups $ find /path -type f -name '*~' -print0 | xargs -0 -I % cp -a % ~/backups La cadena a reemplazar puede aparecer varias veces en la parte del comando. Usar ` -Iat all` limita el número de líneas utilizadas cada vez a una.
Truco de la concha: cualquier número
Otra forma de lograr un efecto similar es usar un intérprete de comandos como comando ejecutado y lidiar con la complejidad en ese intérprete, por ejemplo:
$ mkdir ~/backups $ find /path -type f -name '*~' -print0 | xargs -0 sh -c 'for filename; do cp -a "$filename" ~/backups; done' sh La palabra shal final de la línea es para que el intérprete de comandos POSIXsh -c complete $0la parte del "nombre del ejecutable" de los parámetros posicionales (argv). Si no estuviera presente, el nombre del primer archivo coincidente se asignaría a $0y el archivo no se copiaría a ~/backups. También se puede usar cualquier otra palabra para completar ese espacio en blanco, my-xargs-scriptpor ejemplo.
Dado que cpacepta varios archivos a la vez, también se puede hacer simplemente lo siguiente:
$ find /path -type f -name '*~' -print0 | xargs -0 sh -c 'if [ $# -gt 0 ]; then cp -a "$@" ~/backup; fi' sh Este script se ejecuta cpcon todos los archivos que se le proporcionan cuando se le pasan argumentos. Hacerlo es más eficiente ya que solo cpse realiza una invocación de por cada invocación de sh.
Problema del separador
Muchas utilidades de Unix están orientadas a líneas. Estas pueden funcionar xargssiempre que las líneas no contengan ', ", o un espacio. Algunas utilidades de Unix pueden usar NUL como separador de registros (por ejemplo, Perl (requiere -0y \0en lugar de \n), locate(requiere usar -0), find(requiere usar -print0), grep(requiere -zo -Z), sort(requiere usar -z)). Usar -0para xargsresuelve el problema, pero muchas utilidades de Unix no pueden usar NUL como separador (por ejemplo head, , tail, ls, echo, sed, tar -v, wc, which).
Pero a menudo la gente olvida esto y asume xargsque también está orientado a líneas, lo cual no es el caso (por defecto xargssepara por saltos de línea y espacios en blanco dentro de las líneas, las subcadenas con espacios en blanco deben ir entre comillas simples o dobles).
El problema del separador se ilustra aquí:
# Crea algunos objetivos para practicar tocando el archivo importante touch 'not important_file' mkdir -p '12" records' encontrar . -nombre no \* | cola -1 | xargs rm encontrar \! -nombre . -tipo d | cola -1 | xargs rmdir Ejecutar lo anterior hará important_fileque se elimine, pero no eliminará ni el directorio llamado 12" records, ni el archivo llamado not important_file.
La solución adecuada es usar la -print0opción específica de GNU, pero tail(y otras herramientas) no admiten cadenas terminadas en NUL:
# utiliza los mismos comandos de preparación que arriba find . -name not \* -print0 | xargs -0 rm encontrar \! -nombre . -tipo d -imprimir0 | xargs -0 rmdir Al usar esta -print0opción, las entradas se separan mediante un carácter nulo en lugar de un salto de línea. Esto es equivalente al comando más detallado: o más corto, cambiando al modo orientado a líneas (no POSIX) con la opción (delimitador):find.-namenot\*|tr\\n\\0|xargs-0rmxargs-dfind.-namenot\*|xargs-d'\n'rm
pero en general se debería preferir usar -0con , ya que los saltos de línea en los nombres de archivo siguen siendo un problema.-print0
GNU paralleles una alternativa xargsdiseñada para tener las mismas opciones, pero orientada a líneas. Por lo tanto, al usar GNU Parallel en su lugar, lo anterior funcionaría como se espera. [ 7 ]
Para entornos Unix donde xargsno admite -0ni la -dopción (por ejemplo, Solaris, AIX), el estándar POSIX establece que se puede simplemente escapar cada carácter con una barra invertida: . [ 8 ] Alternativamente, se puede evitar el uso de xargs por completo, ya sea utilizando GNU parallel o utilizando la funcionalidad de .find.-namenot\*|sed's/\(.\)/\\\1/g'|xargsrm-exec ... +find
Operando sobre un subconjunto de argumentos a la vez.
Es posible que se trate de comandos que solo aceptan uno o dos argumentos a la vez. Por ejemplo, el diffcomando opera con dos archivos simultáneamente. La -nopción xargsespecifica cuántos argumentos se deben proporcionar al comando. El comando se ejecutará repetidamente hasta que se agoten todos los argumentos. Tenga en cuenta que en la última ejecución podría recibir menos argumentos de los deseados si la entrada es insuficiente. Utilice esta opción xargspara dividir la entrada en dos argumentos por línea:
$ eco { 0 ..9 } | xargs -n 2 0 1 2 3 4 5 6 7 8 9Además de ejecutarse en función de un número específico de argumentos a la vez, también se puede invocar un comando para cada línea de entrada con la -L 1opción. Se puede usar un número arbitrario de líneas a la vez, pero una es lo más común. Así es como se podría realizar diffcada commit de Git contra su padre. [ 9 ]
$ git log --format = "%H %P" | xargs -L 1 git diff Problema de codificación
El procesamiento del separador de argumentos xargsno es el único problema al usar el xargsprograma en su modo predeterminado. La mayoría de las herramientas de Unix que se usan a menudo para manipular nombres de archivo (por ejemplo sed, , basename, sort, etc.) son herramientas de procesamiento de texto. Sin embargo, los nombres de ruta de Unix no son realmente texto. Consideremos un nombre de ruta /aaa/bbb/ccc. El directorio /aaa y su subdirectorio bbb pueden ser creados en general por diferentes usuarios con diferentes entornos. Esto significa que estos usuarios podrían tener una configuración regional diferente, y eso significa que aaa y bbb ni siquiera tienen que tener necesariamente la misma codificación de caracteres. Por ejemplo, aaa podría estar en UTF-8 y bbb en Shift JIS. Como resultado, un nombre de ruta absoluto en un sistema Unix puede no ser procesado correctamente como texto bajo una sola codificación de caracteres. Las herramientas que dependen de que su entrada sea texto pueden fallar con tales cadenas.
Una solución alternativa a este problema consiste en ejecutar dichas herramientas en el entorno C, que procesa los bytes de entrada tal cual. Sin embargo, esto modificará el comportamiento de las herramientas de maneras que el usuario podría no esperar (por ejemplo, es posible que no se cumplan algunas de sus expectativas sobre el comportamiento de la conversión a minúsculas).
Referencias
- ↑ "Lista de acrónimos de Unix: la lista completa" . www.roesler-ac.de . Archivado del original el 16 de julio de 2012. Consultado el 12 de abril de 2020 .
- ↑ "Adaptaciones nativas para Win32 de algunas utilidades GNU" . unxutils.sourceforge.net . Archivado del original el 9 de febrero de 2006. Consultado el 11 de agosto de 2025 .
- ↑ "Herramientas de procesamiento de texto para Windows" . Archivado del original el 22/03/2022 . Consultado el 22/03/2022 .
- ↑ IBM . "IBM System i Versión 7.2 Programación Qshell" (PDF) . Archivado (PDF) del original el 18-09-2020 . Recuperado el 05-09-2020 .
- ↑ "Preguntas frecuentes sobre las utilidades principales de GNU" . Archivado del original el 23 de noviembre de 2015. Consultado el 7 de diciembre de 2015 .
- ↑ "La longitud máxima de los argumentos para un nuevo proceso" . www.in-ulm.de .
- ↑ Diferencias entre xargs y GNU Parallel Archivado el 29/07/2016 en Wayback Machine . GNU.org Archivado el 22/02/2011 en Wayback Machine . Consultado en febrero de 2012.
- ↑ – Shell and Utilities Reference, The Single UNIX Specification , Versión 5 de The Open Group
- ↑ Cosmin Stejerean. "Cosas que (probablemente) no sabías sobre xargs" . Archivado del original el 26 de noviembre de 2015. Consultado el 7 de diciembre de 2015 .
Enlaces externos
- : construir listas de argumentos e invocar utilidades – Referencia de shell y utilidades, Especificación única de UNIX , Versión 5 de The Open Group
Páginas del manual
- – Referencia de GNU Findutils
- : construir lista(s) de argumentos y ejecutar utilidad – Manual de comandos generales de FreeBSD
- : construir lista(s) de argumentos y ejecutar utilidad – Manual de comandos generales de NetBSD
- : construir lista(s) de argumentos y ejecutar utilidad – Manual de comandos generales de OpenBSD
- : construir listas de argumentos e invocar utilidades – Manual de referencia de comandos de usuario de Solaris 11.4
- utilidades de procesamiento de texto de Unix
- Utilidades Unix SUS2008
- Órdenes del Plan 9
- Comandos de Qshell para IBM i