A veces ejecuto xargs
trabajos largos durante la noche y es realmente molesto descubrir en la mañana que xargs
murió en algún punto intermedio, por ejemplo, debido a una falla de segmentación en un solo caso especial, como sucedió esta noche.
Si incluso un xargs
niño es asesinado, no procesa más entradas:
Consola 1:
[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>
Consola 2:
[09:35:54] kill 5601
¿De alguna manera puedo evitar que se xargs
detenga para procesar más entradas una vez que un proceso secundario falle y en su lugar continúe procesando?
xargs
versión 4.4.2debian wheezy
y parece que todo funciona bien incluso si elimino unsleep
proceso específico . ¿Qué versión dexargs
estás usando? Es posible que hayan solucionado el problema en la última versión.xargs ... bash -c '...;exit 0'
o incluso?xargs ... bash -c '... || echo erk'
parallel -j 1
es una posible solución de pirateo.Respuestas:
No puedes. De las
xargs
fuentes en savannah.gnu.org :No hay bandera alrededor de ese cheque, o alrededor de la función que lo llama. Parece estar relacionado con los procesos máximos, lo que supongo que tiene sentido: si configura los procesos máximos lo suficientemente altos, no se molestará en verificar hasta que llegue al límite, lo que podría llegar a ser nunca.
Una mejor solución para lo que está tratando de hacer podría ser usar GNU Make :
Luego:
tendrá el mismo efecto y le dará un control mucho mejor.
fuente
Parecería que uno de los coloquialismos más obvios solo es mencionado por otras propuestas.
Es decir, puede usar lo siguiente:
para "forzar el éxito".
Tenga en cuenta que esto está en la línea de la propuesta de lornix (solo que no en muchas palabras).
De todos modos, dado que esto ignora efectivamente el estado real de salida del proceso, me aseguraría de que considere guardar de alguna manera el estado del subproceso para el análisis post mortem. P.ej:
El
true
aquí es algo redundante, por lo que puede escribirse mejor como:Como probablemente nos gustaría saber cuándo no se pudo tocar el archivo 'fallido'. En otras palabras, ya no estamos ignorando la falla, estamos tomando nota y continuando.
Y, después de considerar la naturaleza recursiva de este problema, quizás veamos exactamente por qué xargs no hace que ignorar la falla sea fácil. Como nunca es una buena idea, en su lugar, debería mejorar el manejo de errores dentro del proceso que está desarrollando. Sin embargo, creo que esta noción es más inherente a la "filosofía Unix" en sí misma.
Finalmente, supongo que esto es también a lo que James Youngman alude al recomendar
trap
, que presumiblemente podría usarse de manera similar. Es decir, no ignore el problema ... atrape y maneje o se despierte un día y descubra que ninguno de los subprogramas tuvo éxito ;-)fuente
Uso
trap
:Alternativamente, cambie de shell a otro idioma en el que también puede configurar controladores de señal.
Tenga en cuenta también que después
bash -c foo..
debe especificar el valor que$0
debe tomar (aquífnord
) para que la primera palabra producida porseq
no se coma.fuente
Ponga otro comando allí para 'comer' la señal del programa moribundo.
Probé su ejemplo, inicialmente como se muestra para demostrar el problema ... 'killall sleep' mata el proceso de sueño, interrumpe bash y xargs se cierra.
Como prueba, pegué un comando de tipo 'ejecutar otro comando' entre xargs y bash ... en este caso '/ usr / bin / time'. esta vez (sin juego de palabras), el sueño de Killall mata el proceso de sueño, pero los xargs continúan.
Dirigiría la salida del tiempo a / dev / null, y esto haría exactamente lo que está buscando sin una gran reescritura de su proceso existente.
Me imagino que si reflexiono por un momento podría idear otro programa para hacer lo mismo sin la charla stderr de '/ usr / bin / time'. O incluso escribir uno yo mismo, es solo un 'fork' (o derivado exec ()).
Recuerde usar '/ usr / bin / time', ya que no estoy seguro de que el 'tiempo' incorporado de bash haga lo mismo 'comer' la señal.
fuente
time
para este propósito seríaenv
, ya que todo lo que hace es agregar cero o más variables opcionales al entorno del programa que ejecuta. No emite ninguna salida propia, y el código de retorno del programa invocado se devolverá a lo que se llameenv
.Ni
time
tampocoenv
funcionó para mí (que pasan a lo largo del valor de retorno de su programa infantil) así que escribíbliss
:luego
chmod u+x ~/bliss
y algo como
find_or_similar | xargs ~/bliss fatally_dying_program.sh
fuente