2009-03-25 22 views
6

¿Alguien me puede dar un ejemplo del uso de xargs en la siguiente operación?Cómo usar "xargs" correctamente cuando la lista de argumentos es demasiado larga

tar c $dir/temp/*.parse\ 
    | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 

me sale el error de fiesta "/bin/tar: Lista de argumentos demasiado tiempo"

Particularily que estoy tratando de hacer la compresión LZMA en cerca de 4.500 archivos; así que esto no es sorprendente. ¡Simplemente no sé cómo modificar lo anterior para usar xargs y deshacerme del error! Gracias.

Respuesta

10

Ampliando CristopheDs respuesta y asumiendo está utilizando bash:

tar c --files-from <(find $dir/temp -maxdepth 1 -name "*.parse") | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 

La razón xargs no le ayuda aquí es que va a hacer múltiples invocaciones hasta que todos argumentos han sido utilizados. Esto no lo ayudará aquí ya que creará varios archivos tar, que no desea.

+0

cometí el error de hacer múltiples invocaciones de alquitrán antes, pensando al ponerlas en {...} | lzma ... funciona pero luego imprimiría el encabezado del tar nuevamente cada vez: p –

+0

Excelente, esta es una solución perfecta; ¡Gracias! – jparanich

+1

En caso de que alguien encuentre esto y no esté claro * cómo * funciona, '<(comando)' en bash crea un "descriptor de archivo nombrado" adjunto a la salida de 'comando'. Entonces, en este caso, 'tar' ve un argumento como' --files-from/dev/fd123', pero leer desde el "archivo" '/ dev/fd123' solo le da la salida de' find', sin la necesidad para un archivo temporal real. – IMSoP

4

Utilice find para insertar los nombres de archivo 'deseados' en un archivo temporal, y luego use tar con la opción de línea de comando '--files-from'.

Editar:

o tubería directamente entre sí para evitar el archivo temporal.

So: use find para listar los nombres de archivo deseados | tar ... --files-de

4

Quizás quieras algo como esto?

find $dir/temp/ -name '*.parse' -print0 | tar --null -T - -c | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 
+1

+1, esto es lo que estaba a punto de escribir. – ashawley

0

Ya que estás en Linux, tienen GNU tar, y se puede utilizar la opción '-F -' o '--files-from' para leer los nombres de los archivos.

Sin embargo, también se puede utilizar:

--use-compresa-programa = "lzma -9"

para especificar el programa de compresión de usar, y simplemente dar las compresas nombre de archivos como el objetivo archivo para el comando 'tar'.

Esto fue necesario para la compresión 'bzip2' antes de agregar la opción '-j'.

11

Como una nota:

evitar siempre, siempre xargs (1). Es una herramienta rota y solo es remotamente útil si la usa con la opción -0. Incluso entonces, casi siempre es mejor usar la opción -exec de find (1), o un bucle simple para o while.

¿Por qué es xargs tan malo? En primer lugar, divide la entrada en el espacio en blanco, lo que significa que todos los nombres de archivo que contienen el espacio en blanco causará estragos. En segundo lugar, es intenta para ser un listillo, y parse cotizaciones para usted. Lo cual solo lleva a más dolores de cabeza cuando lo usa en nombres de archivos que contienen citas como parte del nombre de archivo, como canciones: "No me quiero perder nada.mp3".Esto solo hará que xargs vomite y te maldiga cuando dices mal su entrada. No, no lo hizo: debería aprender que las cotizaciones no pertenecen a los datos de entrada, pertenecen a las secuencias de comandos de shell, y xargs no tiene nada que tratar de analizarlas.

Tenga en cuenta que xargs (1) no divide el espacio en blanco ni el análisis de comillas cuando pasa -0 a él. Hace lo correcto , que es utilizar bytes NULL para delimitar nombres de archivo. Pero eso significa que debe darle una entrada que use nombres de archivo NULL delimitados por bytes (como "find -foo -print0"). Lo cual nos lleva de vuelta a: es mejor usar find -exec: "find -foo -exec bar {} +".

+0

historia/explicación agradable, increíble, ¡muy apreciada! – jparanich

+1

Esta es la razón por la cual GNU Parallel se hizo: http://www.gnu.org/software/parallel/history.html –

Cuestiones relacionadas