Si se requiere realizar un respaldo (copia) de muchos archivos, puede ser que el listado completo no entre en el buffer que tienen reservado la shell, y nos mostraría el siguiente error :
Argument list too long
Esto lo podemos solucionar con el comando XARGS, mediante el parámetro -I indicamos una cadena que luego en el comando vamos a usar para pasar el parámetro. Para pasar el listado de ficheros podemos usar un simple ls o bien un find para filtrar mejor los ficheros que queremos.
1 |
ls | xargs -I ARG cp ARG /var/www/destino |
Las opciones del xargs pueden se usadas para construir comandos extremamente poderosos.
Opción -i
Para ejemplificar esto y comenzar a entender las principales opciones de esta instrucción, vamos a suponer que tenemos que borrar todos los archivos con extensión .txt en el directorio actual y presentar sus nombres en pantalla. Veamos que podemos hacer:
1 2 |
find . -type f -name "*.txt" | \ xargs -i bash -c "echo borrando {}; rm {}" |
La opción -i del xargs cambia pares de llaves ({}) por la cadena que está recibiendo a través del pipe (|). Entonces en este caso las llaves ({}) serán cambiadas por los nombres de los archivos que satisfagan al comando find.
Opción -n
Veamos este pequeño juego que vamos a hacer con el xargs:
1 2 3 4 5 6 7 8 |
$ ls | xargs echo > arch.ls $ cat arch.ls arch.ls arch1 arch2 arch3 $ cat arch.ls | xargs -n1 arch.ls arch1 arch2 arch3 |
Cuando mandamos la salida del ls hacia el archivo usando el xargs comprobamos lo que ya dijimos, o sea, el xargs manda todo lo que sea posible (lo suficiente para no generar una sobrecarga en la pila) de una vez sola. En seguida, usamos la opción -n 1 para listar uno por uno. Sólo para estar seguros, mira el ejemplo siguiente, donde listaremos dos archivos en cada línea:
1 2 3 |
$ cat arch.ls | xargs -n 2 arch.ls arch1 arch2 arch3 |
Sin embargo, la línea de arriba podría (y debería) ser escrita sin usar el pipe (|), de la siguiente forma:
1 |
$ xargs -n 2 < arch.ls |
Opción -p
Otra excelente opción del xargs es -p, en la cual el sistema pregunta si tu realmente deseas ejecutar el comando. Digamos que en un directorio tengas archivos con la extensión .bug y .ok, los .bug tienen problemas que después de corregidos son grabados como .ok. Echa una mirada a la lista de este directorio:
1 2 3 4 5 6 7 8 |
$ ls dir arch1.bug arch1.ok arch2.bug arch2.ok ... arch9.bug arch9.ok |
Para comparar los archivos buenos con los defectuosos, hacemos:
1 2 3 4 |
$ ls | xargs -p -n2 diff -c diff -c arch1.bug arch1.ok ?...y .... diff -c arch9.bug arch9.ok ?...y |
Opción -t
Para finalizar, el xargs también tenemos la opción -t, donde va mostrando las instrucciones que montó antes de ejecutarlas. Me gusta mucho esta opción para ayudar a depurar el comando que fue montado.