impedire agli xargs di uscire dall'errore


27

Secondo la pagina man, xargs si chiuderà se una delle righe di esecuzione esce con un errore di 255:

Se una qualsiasi invocazione del comando termina con uno stato di 255, xargs si interromperà immediatamente senza leggere ulteriori input. Quando questo accade, viene emesso un messaggio di errore su stderr.

Come posso ottenere xargs per non farlo?

Ho un lavoro batch di circa 1500 righe che voglio eseguire, 50 righe alla volta. Stavo scoprendo che stava sempre morendo a una certa linea e non completando il lavoro. Non bene!

Una domanda ancora migliore, la domanda che descrive cosa sto cercando di fare, è:

Come posso eseguire uno script batch di 1500 righe, 50 righe alla volta, in modo che non esca dal processo nel mezzo e che l'output venga acquisito in un file di registro di qualche tipo?

Risposte:


12

Potresti avvolgere lo script perl con un altro semplice script bash:

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

Questo chiamerà real-command passandogli tutti i parametri che passi a questo falso-comando e restituirà sempre un codice di uscita 0 (il che significa che ha sempre successo) e xargs non si fermerà mai con questo.



9

È possibile scrivere l'invocazione di xargs per mascherare i codici di ritorno delle righe di comando. Con qualcosa di simile al seguente, i xargscodici di uscita non verranno mai restituiti da un comando simile :

xargs sh -c "somecommand || :"

Ho trovato una buona soluzione: assicurati che i comandi in fase di elaborazione non terminino con uno stato 255! Dettagli aggiuntivi Il comando in elaborazione è uno script Perl. La funzione Perl die () veniva utilizzata in diversi punti per uscire se si verificava un errore critico (ad es. Impossibile connettersi a un database). Tuttavia, die () esce sempre con stato di errore 255. La soluzione in questo caso era sostituire die () con una combinazione di print ed exit (), insieme a un codice di errore più ragionevole (in questo caso "1" funzionava).
JDS,

6

Ho appena trovato una risposta divertente a questa, anche se la sua utilità dipenderà dal comando che stai cercando di eseguire.

Se stai usando xargs per assemblare un elenco di comandi, puoi ottenere questo comportamento dicendo a xargs di eseguire l'eco del comando, quindi eseguire il piping su bash.

Ad esempio, se stai cercando di eliminare un elenco di cose che potrebbero esistere o meno:

# 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

Funziona perché, in primo luogo, xargs chiama sempre e solo echo, quindi non vedrà alcun errore. Quindi secondo, perché il comportamento predefinito di bash è quello di continuare l'esecuzione dopo un'istruzione fallita.

Per essere più specifico sul mio caso, lo stavo usando per rimuovere un sacco di vecchie versioni dell'applicazione da AWS ElasticBeanstalk in questo modo:

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

I seguenti lavori di costruzione per me:

ls | xargs -I % svn upgrade %

Anche se l'aggiornamento svn non è riuscito su alcuni elementi, il processo è stato continuato


3

Se si utilizzava xargscon find, utilizzare invece l' -execopzione di find:

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

1
Salve. potrei usarlo, ma l'opzione -exec non parallelizza le operazioni come può fare con xargs
JDS,

2
Grazie - non sapevo che xargspotesse eseguire comandi in parallelo. Freddo. Se vuoi solo minimizzare il numero di invocazioni di comandi, -execha un +parametro.
Roger Dahl,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.