impedir que xargs saia por erro


27

De acordo com a página do manual, o xargs será encerrado se uma das linhas de execução sair com um erro 255:

Se qualquer chamada do comando sair com um status 255, o xargs será interrompido imediatamente sem ler mais nenhuma entrada. Uma mensagem de erro é emitida no stderr quando isso acontece.

Como posso obter xargs para não fazer isso?

Eu tenho um trabalho em lote de mais ou menos 1500 linhas que quero executar, 50 linhas por vez. Eu estava descobrindo que estava sempre morrendo em uma determinada linha e não concluindo o trabalho. Não é bom!

Uma pergunta ainda melhor, a pergunta que descreve o que estou tentando fazer, é:

Como posso executar um script em lotes de 1500 linhas, 50 linhas por vez, para que ele não saia do trabalho no meio e para que a saída seja capturada em algum tipo de arquivo de log?

Respostas:


12

Você pode agrupar o script perl com outro script simples do bash:

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

Isso chamará o comando real passando todos os parâmetros que você passa para esse comando falso e sempre retornará um código de saída 0 (o que significa que sempre é bem-sucedido) e o xargs nunca irá parar com isso.



9

Você pode escrever sua chamada de xargs para mascarar os códigos de retorno de suas linhas de comando. Com algo como o seguinte, xargsnunca verá códigos de saída retornados por algum comando :

xargs sh -c "somecommand || :"

Encontrei uma boa solução: verifique se os comandos que estão sendo processados ​​não saem com um status 255! Detalhes adicionais O comando que está sendo processado é um script Perl. A função Perl die () estava sendo usada em vários locais para sair se algum erro crítico ocorresse (por exemplo, não foi possível conectar-se a um banco de dados). No entanto, o die () sempre sai com o status de erro 255. A solução nesse caso foi substituir o die () por uma combinação de print e exit (), junto com um código de erro mais razoável ("1" funcionou nesse caso).
JDS 11/07

6

Acabei de encontrar uma resposta divertida para essa, embora sua utilidade dependa do comando que você está tentando executar.

Se você estiver usando o xargs para montar basicamente uma lista de comandos, poderá obter esse comportamento dizendo ao xargs para ecoar o comando e, em seguida, canalizando para o bash.

Por exemplo, se você estiver tentando excluir uma lista de itens que podem ou não 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

Isso funciona porque, primeiro, o xargs está sempre chamando eco, portanto, não verá nenhum erro. Segundo, porque o comportamento padrão do bash para continuar a execução após uma instrução com falha.

Para ser mais específico sobre o meu caso, eu estava usando isso para remover várias versões antigas de aplicativos do AWS ElasticBeanstalk da seguinte maneira:

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

Trabalhos de construção seguintes para mim:

ls | xargs -I % svn upgrade %

Mesmo que a atualização svn falhe em algum elemento, o processo foi continuado


3

Se você estava usando xargscom find, use a -execopção de find:

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

1
Olá. eu poderia usar isso, mas a opção -exec não paralelizar as operações do caminho usando xargs pode e
JDS

2
Obrigado - eu não sabia que xargspoderia executar comandos em paralelo. Legal. Se você deseja minimizar apenas o número de chamadas de comando, -execpossui um +parâmetro
Roger Dahl
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.