Falha quando um comando falha no subcomando

1

Eu quero executar um comando em uma lista de diretórios: gradle --build-cache . Além disso, o diretório precisa começar com a string 'Project' e não terminar com 'Test'. Consegui fazer isso com este comando:

find . -maxdepth 1 -type d \( ! -name . \) -name "Project*" ! -name "*Test*" -exec sh -c "cd '{}' && pwd && gradle --build-cache" \;

Mas meu problema é que o comando gradle pode falhar. Se eu iniciar o comando sozinho, ele retornará 'exit 1', mas se um dos comandos do diretório falhar, ele não retornará a falha e o script continuará. No final, o loop retorna sucesso exit 0 ...

Como posso parar a execução do loop quando o comando gradle falhou e retornar para o comando geral um exit 1 ?

Obrigado :)

    
por Fred 01.12.2017 / 15:45

3 respostas

3

Esta é uma pergunta semelhante a link . Estou citando as duas formas mais prováveis de como alcançar seu objetivo.

A maneira mais fácil é usar xargs , mas isso funciona somente se você não tiver espaço em nenhum caminho que o comando find possa encontrar:

find … -print0 | xargs -0 -n1 invalid_command

Você também pode se livrar de encontrar e usar globalização recursiva ou implementar uma pesquisa recursiva por conta própria (duvido que sua árvore de diretórios seja profunda o suficiente para causar um problema) se você estiver preso a um Bash mais antigo (abaixo 4.xx ).

shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done

Além disso, se você não precisa que seja um one-liner, você pode primeiro encontrar todos os diretórios, salvá-los, por exemplo. para um arquivo temporário (use mktemp para isso), e então faça qualquer coisa que você precisa com a lista. Filtre mais, execute comandos neles ...

    
por 01.12.2017 / 17:24
0

Você pode testar para ver se o último comando saiu com um erro e depois emitir um comando exit adicionando if [[ $? != 0 ]] ; then exit ; fi à linha.

Por favor, note que, se o trecho de código fornecido fizer parte de um script maior, este sairá completamente do script. Você pode querer considerar reescrevê-lo em um loop for ou while para que você possa usar break .

    
por 01.12.2017 / 16:03
0

Apenas por diversão, aqui está uma resposta find -only. Eu não acho que você pode fazer isso apenas com os recursos POSIX do find , mas já que você já está usando alguns GNUisms, você pode tirar vantagem do -quit primitivo:

$ find -exec command {} \; -o -quit

Isso faz com que find seja imediatamente fechado assim que command falhar (ou seja, retornar um código de saída diferente de zero). Agora, para forçar o find a sair com um status diferente de zero, você precisa fazer com que ele falhe antes do -quit . Uma maneira de fazer isso é

$ find -exec command {} \; -o -fprint /dev/full -quit

já que todas as gravações em /dev/full falharão. Você receberá uma mensagem de erro como

find: ‘/dev/full’: No space left on device

que você pode filtrar com 2>/dev/null , se quiser.

Se você estava usando o NetBSD encontra , você pode fazer isso em vez disso:

$ find -exec command {} \; -o -exit 1
    
por 04.12.2017 / 21:58