2009-12-13 22 views
20

Estoy bastante confundido sobre esto. Necesita algunas aclaracionesComprender el comando UNIX xargs

Ejemplo 1:

pgrep string | xargs ps 

Ejemplo 2:

find . | xargs grep whatever 

Desde el Ejemplo 1, deduzco que es de esta manera:

búsqueda de una "cadena" que es forma parte del nombre del proceso en ejecución y devuelve los ID de proceso de todas las coincidencias a 'xargs ps' -> que simplemente se agrega ps para los partidos (que son propios del proceso-ids) para obtener el mismo resultado que:

ps <processid> 

Puede alguien explicar lo que realmente hace xargs en este caso?

del Ejemplo 2, deduzco que es de esta manera:

Es para buscar un poco de "cadena" de forma recursiva del directorio de trabajo actual. Aquí, ¿cómo funciona exactamente 'xargs'?

Yo era de la opinión de que 'xargs' agrega repetidamente datos de entrada estándar al 'argumento' dado a xargs (que generalmente es un comando de UNIX por sí mismo).

De xargs() página hombre:

xargs lee artículos de la entrada estándar, delimitadas por espacios en blanco (que se puede protegido con comillas dobles o individuales o una barra invertida) o saltos de línea, y ejecuta el comando (por defecto es/bin/echo) una o más veces con cualquier argumento inicial seguido de elementos leídos de la entrada estándar. Las líneas en blanco en la entrada estándar se ignoran.

+0

xargs actúa como el "subtitution comando" (al menos con Bash). Convierte resultados de líneas múltiples (verticales) en una lista de una línea de argumentos de tokens (horizontal). (Tenga en cuenta que puede filtrar los resultados un poco (usando sed para ex) antes de pasarlos a xargs). Además, xargs maneja el error «_muchos argumentos_ que puede ocurrir antes de Linux kernel 2.6.23 (Ver [wikipedia] (https://en.wikipedia.org/wiki/Xargs)). Aquí está [otro hilo útil] (http://unix.stackexchange.com/questions/24954/when-is-xargs-needed) – Stphane

Respuesta

37

En generales xargs se utiliza como esto

prog | xargs utilidad

donde se espera prog a la salida de uno o más de nueva línea/espacio separado resultados. El truco es que xargs no! nessarly llame a utilidad una vez para cada resultado, en su lugar divide la lista de resultados en sublistas y llama a utilidad para cada sublista. Si desea forzar a xargs a llamar a la utilidad para cada resultado individual, deberá invocarlo con xargs -L1.

Tenga en cuenta que xargs que promete que la lista secundaria enviado a utilidad es más corta que ARG_MAX (esto es lo que evita los temidos Lista de argumentos a largas errores).Usted puede obtener el valor actual de ARG_MAX usando getconf ARG_MAX

+1

Bueno, esto es algo con lo que podría identificarme, pero ahora se ha convertido en un infierno mucho más confuso. Sé la razón básica por la que xargs está ahí, pero se complica cuando veo que se usa para más de un propósito (de diferentes maneras). – halluc1nati0n

+7

Considera este comando "find/etc -type d -depth 1 | xargs echo" que imprime todos los directorios en la carpeta/etc (pero no en sus subdirectorios). Como el eco toma múltiples argumentos, el resultado es una línea larga "/ etc/dir1/etc/dir2 ...". Si en su lugar llama a "find/etc -type d -depth 1 | xargs -L1 echo", echo se invoca una vez para cada resultado, lo que hace que cada directorio de/etc se imprima en una línea por sí mismo. –

+0

¿Cómo paso comandos u opciones a la utilidad? Diga, ¿quiero ejecutar uglifyjs y especificar y exportar la carpeta para la entrada que entra a xargs? http://stackoverflow.com/questions/43149786/how-to-process-files-in-nested-directories – Costa

2

xargs se utiliza normalmente para argumentos agrupar de manera que usted no recibe un error de "demasiados argumentos", que se produce cuando se pasa un gran número de argumentos a un comando

6
$ echo 'line1 
> line2 
> line3 
> ... 
> lineN ' | xargs cmd1 -a -b 

se traducirá en:

$ cmd1 -a -b line1 line2 line3 ... lineN 

xargs se romperá cmd1 ... en varias ejecuciones de cmd1 si el número de líneas se hace demasiado grande.

xargs se puede utilizar para muchas otras tareas relacionadas con pasar las líneas stdin como argumentos posicionales. Eche un vistazo a la opción capital -P en xargs(1) para ejecutar varias instancias de un comando en paralelo.

1
#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a 
done 

el comando

$sh myscript 1 2 3 4 5 

rendirá

1 
2 
3 
4 
5 

pero

$sh myscript 1 2 3 4 5 6 7 8 9 10 11 
se supera

no funcionará ya que el número máximo de parámetros (no estoy realmente seguro de lo el máximo es, pero digamos que es 10 este ejemplo!)

Para evitar esto podríamos utilizar

#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a | xargs echo 
done 

podríamos luego ejecutarlo como esto

$sh myscript "1 2 3 4 5" "6 7 8 9 10 11" 

y obtener el resultado correcto, ya que hay sólo 2 parámetros

+2

No sé cuál es el máximo, pero definitivamente no es 10. Y puedes usar $ @ en lugar de $ *. este no es un muy buen ejemplo de cómo usar xargs – ghostdog74

9

Un buen ejemplo de lo que hace xargs es tratar de obtener sumas de comprobación clasificadas para cada archivo en un directorio usando find.

find . | cksum | sort 

devuelve solo una suma de comprobación, y no está claro para qué sirve la suma de comprobación. No es lo que queremos La tubería envía el stdout de find en stdin para cksum. Lo que cksum realmente quiere es una lista de argumentos de línea de comando, p.

cksum file001.blah file002.blah file003.blah 

informará tres líneas, una por archivo, con las sumas de comprobación deseadas. Xargs hace el truco de magia: convierte la salida estándar del programa anterior en una línea de comando temporal y oculta para pasar a la siguiente. La línea de comandos que funciona es:

find . | xargs cksum | sort 

Nota ninguna tubería entre xargs y cksum.

+1

por cierto, este es el ingrediente principal en mi receta para encontrar archivos duplicados en dos o más directorios, incluso si sus nombres son diferentes. – DarenW

+0

gracias por la comprensión y la adición de verbose to xargs da comando en acción. encontrar . | xargs --verbose cksum | tipo – kumar

Cuestiones relacionadas