Procesamiento paralelo de untar/remove en el script de shell de Unix

Pregunta:

Quiero descomprimir un archivo tar que tiene muchos archivos tar dentro de sí mismo y eliminar los archivos en todos los archivos tar y quiero que todos estos procesos se ejecuten en paralelo en las secuencias de comandos bash de Unix.

Condiciones:

  1. El script debería devolver un error si algún proceso de descompresión/eliminación tiene algún error.
  2. Solo debería devolver el éxito después de que todos los procesos N (descomprimir y eliminar) se completen correctamente.

Solución propuesta:

 mkdir a
 tar -C a -xvf b.tar
 cd a
 for i in *
 do
 rm -r $i &
 done

preguntado el 03 de mayo de 12 a las 21:05

¿Es correcta mi solución? y en este momento, no obtengo el estado de salida de los procesos en segundo plano. -

Quiero implementar esto, "A medida que inicia cada proceso en segundo plano, ¡ahorre $! que es el pid del proceso en segundo plano. Después de iniciar todo el proceso, tendrá todos los pid. Ahora espere uno por uno para cada pid, con "esperar $pid". ."... ¿cómo implementar eso? -

Por favor, no manipule una pregunta más allá del reconocimiento después de obtener una respuesta. -

¿Cuál es el propósito del ejercicio? En general, no tiene sentido, excepto como una pregunta de estilo de tarea, porque parece que desea eliminar todo lo que extrae. Entonces, ¿por qué molestarse con la extracción? -

¡Se preguntó en una entrevista! -

3 Respuestas

Si tiene GNU Parallel http://www.gnu.org/software/parallel/ instalado puedes hacer esto:

tar xvf foo.tgz | perl -ne 'print $l;$l=$_;END{print $l}' | parallel rm

Es útil si no tiene espacio para extraer el archivo tar.gz completo, pero necesita procesar los archivos a medida que los desempaqueta:

tar xvf foo.tgz | perl -ne 'print $l;$l=$_;END{print $l}' | parallel do_stuff {}\; rm {}

Puede instalar GNU Parallel simplemente de la siguiente manera:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

Vea los videos de introducción de GNU Parallel para obtener más información: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Respondido 15 Feb 14, 10:02

mkdir a
tar -C a -xvf b.tar
 cd a
 success=$(for i in *
 do
 rm -r $i || echo failed & # if a job fails false will be echoed
 done
 wait)
 # if any of the jobs failed, success will be set to a value other than ""
 [[ -z "$success" ]] && exit 0 || exit 1

contestado el 03 de mayo de 12 a las 22:05

¡Gracias Burton!, ¿qué sentido tiene esto?. ¿Estoy entendiendo esto de la manera correcta?. En lugar de crear un proceso "rm *", estoy creando una cantidad de procesos en paralelo y eliminando archivos para ahorrar tiempo. ¿está bien? - beck03076

En realidad, ahora que lo pienso, esto no funcionará. La variable se establecerá en una subcapa. Haré una edición que funcione. - Burton Samogrado

Sí, usar & hace que el proceso se ejecute en segundo plano, por lo que está eliminando todos los archivos en el directorio a en paralelo. Sin embargo, esta no es una buena manera de hacerlo; Sugiero mirar xargs con la opción -P: cd a && { ls * | xargs -P 4 rm -r; } que ejecutará 4 tareas en paralelo. - Burton Samogrado

Perdone mi tortura, ¿puede modificar ese código para implementar xargs, en realidad esa era mi pregunta? Propuse una solución y quería que la gente de stackoverflow la validara. Desafortunadamente, tuviste que rechazar mi pregunta. ¡Esta bien!. SI puede xargs ese código, adelante. Gracias. - beck03076

Le di el código en mi último comentario. Simplemente reemplace el bucle for en su código original con el código de mi último comentario. Creo que el código de retorno de xargs falla si alguno de los comandos falla, por lo que debería proporcionarle esa información directamente. - Burton Samogrado

La respuesta tar xvf a.tar | tac | xargs -P 4 rm -rv está inspirado en Burton Samogradocomentario de xargs -P

$ mkdir -p a/b/c/d
mkdir: created directory `a'
mkdir: created directory `a/b'
mkdir: created directory `a/b/c'
mkdir: created directory `a/b/c/d'

$ touch a/1 a/2 a/3 a/b/4 a/b/5

$ tar cf a.tar a

$ rm -rfv a
removed directory: `a/b/c/d'
removed directory: `a/b/c'
removed `a/b/4'
removed `a/b/5'
removed directory: `a/b'
removed `a/3'
removed `a/1'
removed `a/2'
removed directory: `a'

$ tar xvf a.tar | tac | xargs -P 4 rm -rv
removed `a/2'
removed `a/1'
removed `a/3'
removed `a/b/5'
removed `a/b/4'
removed directory: `a/b/c/d'
removed directory: `a/b/c'
removed directory: `a/b'
removed directory: `a'

contestado el 23 de mayo de 17 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.