
Estou criando um arquivo sh para executar vários comandos em segundo plano.
Em alguma linha deste arquivo, há um comando para atualizar um arquivo zip como:
zip -d archive.zip file.txt
Este arquivo.txt pode nem sempre fazer parte do archive.zip. Quando não é, o script de shell quebra essa linha com:
zip warning: name not matched
Quero que continue nas linhas seguintes, ignorando a inexistência deste arquivo. Como posso fazer isso?
Responder1
Normalmente, em um script de shell, mesmo uma linha que gera um erro não interromperá a execução do script de shell. Ele apenas irá para a próxima linha.
A exceção notável é se você definiu o sinalizador para sair do shell se algum subcomando falhar. Às vezes, isso é feito adicionando "set -e" próximo ao topo de um script. Se você tiver algo assim em seu script, ele será abortado em qualquer comando do script, retornando um erro. Suas opções neste caso são:
Remova essa opção. Isso pode ter ramificações para o resto do seu script, então não faça isso por capricho.
Desative a opção da seção do script em que você está e ative-a novamente para continuar:
set +e zip -d archive.zip file.txt set -e
Forneça uma saída para a linha com falha para que o shell veja o comando como um sucesso, mesmo que algo falhe. Isso pode ser feito de várias maneiras, mas uma simples é usar o operador OR:
zip -d archive.zip file.txt || true
Isso executará o comando zip, mas se falhar, executará o comando true e o shell pai obterá o código de retorno dele (o que é, obviamente, um sucesso). Você pode ver isso às vezes escrito,
||:
o que é um pouco mais rápido e complicado, mas não mágico;:
Acontece que é um comando no-op integrado ao shell que também retornará um código de erro de sucesso, mesmo que não faça nada.Outra maneira de fazer isso é executar o comando em um subshell, cercando-o para
()
que, embora o comando dentro dele possa falhar, o subshell terá feito seu trabalho para que o script pai comset -e
set não morra. Isso não é ideal para um único comando, mas pode ser útil se você quiser executar um conjunto completo de coisas.
Por outro lado, se você deseja apenas suprimir a mensagem de erro gerada pelo zip, você pode redirecionar o fluxo de erro padrão para /dev/null com ( 2> /dev/null
) para suprimir as mensagens geradas (ou fechá-lo com 2>&-
).