evitar que xargs se cierre por error


27

Según la página de manual, xargs se cerrará si una de las líneas de ejecución sale con un error de 255:

Si alguna invocación del comando sale con un estado de 255, xargs se detendrá inmediatamente sin leer ninguna entrada adicional. Cuando esto sucede, se emite un mensaje de error en stderr.

¿Cómo puedo hacer que xargs no haga esto?

Tengo un trabajo por lotes de aproximadamente 1500 líneas que quiero ejecutar, 50 líneas a la vez. Estaba descubriendo que siempre estaba muriendo en cierta línea y no completaba el trabajo. ¡No está bien!

Una pregunta aún mejor, la pregunta que describe lo que estoy tratando de hacer, es:

¿Cómo puedo ejecutar un script por lotes de 1500 líneas, 50 líneas a la vez, para que no salga del trabajo en el medio y para que la salida se capture en un archivo de registro de algún tipo?

Respuestas:


12

Puede envolver el script perl con otro script bash simple:

#!/bin/bash
real-command "$@" || exit 0

Esto llamará al comando real pasándole todos los parámetros que pasa a este comando falso y siempre devolverá un código de salida 0 (eso significa que siempre es exitoso) y xargs nunca se detendrá con esto.



9

Puede escribir su invocación xargs para enmascarar los códigos de retorno de sus líneas de comando. Con algo como lo siguiente, xargsnunca verá códigos de salida devueltos por algún comando :

xargs sh -c "somecommand || :"

Se me ocurrió una buena solución: ¡asegúrese de que los comandos que se procesan no salgan con un estado 255! Detalles adicionales El comando que se procesa es un script de Perl. La función Perl die () se estaba utilizando en varios lugares para salir si se producía algún error crítico (por ejemplo, no se podía conectar a una base de datos). Sin embargo, die () siempre sale con el estado de error 255. La solución en este caso fue reemplazar die () con una combinación de print y exit (), junto con un código de error más razonable ("1" funcionó en este caso).
JDS

6

Acabo de encontrar una respuesta divertida a esta, aunque su utilidad dependerá del comando que intente ejecutar.

Si está utilizando xargs para armar básicamente una lista de comandos, puede obtener este comportamiento diciéndole a xargs que repita el comando y luego canalizando a bash.

Por ejemplo, si está intentando eliminar una lista de cosas que pueden o no existir:

# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit

# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash

Esto funciona porque, primero, xargs solo llama echo, por lo que no verá ningún error. Luego, segundo, porque el comportamiento predeterminado de bash para continuar la ejecución después de una declaración fallida.

Para ser más específico sobre mi caso, estaba usando esto para eliminar un montón de versiones antiguas de aplicaciones de AWS ElasticBeanstalk de esta manera:

aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
  echo aws elasticbeanstalk delete-application-version \
       --delete-source-bundle --application-name myapp --version-label |\
bash

4

Los siguientes trabajos de construcción para mí:

ls | xargs -I % svn upgrade %

Incluso si la actualización de svn falló en algún elemento, el proceso continuó


3

Si estaba usando xargscon find, use la -execopción de en su findlugar:

find . -name '*.log' -exec somecommand {} \;

1
hola podría usar eso, pero la opción -exec no paraleliza las operaciones de la misma manera que xargs puede y lo hace
JDS

2
Gracias, no sabía que xargspodía ejecutar comandos en paralelo. Guay. Si solo desea minimizar el número de invocaciones de comandos, -exectiene un +parámetro.
Roger Dahl el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.