Às vezes, xargs
trabalho longo da noite para o dia e é realmente irritante descobrir pela manhã que xargs
morreu em algum lugar no meio, por exemplo, devido a uma falha de segmentação em um único caso especial, como aconteceu esta noite.
Se um xargs
filho for morto, ele não processa mais nenhuma entrada:
Console 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>
Console 2:
[09:35:54] kill 5601
De alguma forma, posso impedir que xargs
pare para processar mais entradas depois que um processo filho morre e, em vez disso, continue processando?
xargs
versão 4.4.2debian wheezy
e parece que tudo corre bem, mesmo se eu matar umsleep
processo específico . Qual versãoxargs
você está usando? pode ser que eles tenham corrigido o problema na versão mais recente.xargs ... bash -c '...;exit 0'
ou mesmoxargs ... bash -c '... || echo erk'
parallel -j 1
é uma possível solução de invasão.Respostas:
Não, você não pode. Nas
xargs
fontes em savannah.gnu.org :Não há sinalizador em torno dessa verificação ou em torno da função que a chama. Parece estar relacionado ao max procs, o que, suponho, faz sentido: se você definir max procs alto o suficiente, ele não se incomodará em verificar até atingir o limite, o que talvez você nunca consiga.
Uma solução melhor para o que você está tentando fazer pode ser usar o GNU Make :
Então:
terá o mesmo efeito e lhe dará um controle muito melhor.
fonte
Parece que um dos coloquialismos mais óbvios é mencionado apenas por outras propostas.
Ou seja, você pode usar o seguinte:
para "forçar o sucesso".
Observe que isso é parecido com a proposta de lornix (mas não em tantas palavras).
De qualquer forma, como isso efetivamente ignora o status real de saída do processo, certifique-se de considerar de alguma forma salvar o status do subprocesso para análise post-mortem. Por exemplo:
O
true
aqui é um pouco redundante e, portanto, pode ser melhor escrito como:Como provavelmente gostaríamos de saber quando o arquivo 'falhou' não pôde ser tocado. Em outras palavras, não estamos mais ignorando a falha, estamos tomando nota e continuando.
E, depois de considerar a natureza recursiva desse problema, talvez vejamos exatamente por que o xargs não torna fácil ignorar a falha. Como nunca é uma boa ideia - você deve aprimorar o tratamento de erros no processo que está desenvolvendo. Eu acredito que essa noção, no entanto, é mais inerente à "filosofia Unix" em si.
Por fim, suponho que também é isso que James Youngman alude ao recomendar
trap
, que provavelmente poderia ser usado de maneira semelhante. Ou seja, não ignore o problema ... prenda-o e resolva-o ou você acorda um dia e descobre que nenhum dos subprogramas teve sucesso ;-)fonte
Use
trap
:Alternativamente, mude do shell para outro idioma no qual você também pode definir manipuladores de sinal.
Observe também que, depois de
bash -c foo..
especificar o valor que$0
deve levar (aquifnord
) , para que a primeira palavra produzida porseq
não seja consumida.fonte
Coloque outro comando lá para 'comer' o sinal do programa que está morrendo.
Eu tentei o seu exemplo, inicialmente como mostrado para provar o problema ... 'killall sleep' mata o processo do sono, interrompe o bash e o xargs é encerrado.
Como teste, coloquei um comando do tipo 'execute outro comando' entre xargs e bash ... neste caso '/ usr / bin / time'. desta vez (sem trocadilhos), o sono matador mata o processo de sono, mas o xargs continua.
Você canalizaria a saída do tempo para / dev / null, e isso faria exatamente o que você está procurando, sem uma grande reescrita do processo existente.
Imagino que, se refletir por um momento, poderia criar outro programa para fazer o mesmo sem a conversa stderr de '/ usr / bin / time'. Ou até mesmo escrever um, é apenas um 'fork' (ou derivado exec ()).
Lembre-se de usar '/ usr / bin / time', pois não tenho certeza de que o 'time' interno do bash fará o mesmo 'comer' do sinal.
fonte
time
para esse fim seriaenv
, pois tudo o que faz é adicionar zero ou mais variáveis opcionais ao ambiente do programa que ele executa. Ele não emite saída própria e o código de retorno do programa invocado será passado de volta para o que for chamadoenv
.Nem
time
nemenv
trabalhou para mim (que repassar o valor de retorno do seu programa infantil) então eu escrevibliss
:então
chmod u+x ~/bliss
e algo como
find_or_similar | xargs ~/bliss fatally_dying_program.sh
fonte