Eu fiz o seguinte script:
# !/bin/bash
# OUTPUT-COLORING
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m' # No Color
# FUNCTIONS
# directoryExists - Does the directory exist?
function directoryExists {
cd $1
if [ $? = 0 ]
then
echo -e "${green}$1${NC}"
else
echo -e "${red}$1${NC}"
fi
}
# EXE
directoryExists "~/foobar"
directoryExists "/www/html/drupal"
O script funciona, mas além dos meus ecos, há também a saída quando
cd $1
falha na execução.
testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory
É possível pegar isso?
bash
shell
shell-script
error-handling
Thomas De Wilde
fonte
fonte
test -d /path/to/directory
(ou[[ -d /path/to/directory ]]
no bash) informará se um determinado destino é um diretório ou não e o fará silenciosamente.cd
.directoryExists
.Respostas:
Seu script altera os diretórios à medida que é executado, o que significa que não funcionará com uma série de nomes de caminho relativos. Você comentou mais tarde que só queria verificar a existência do diretório, não a capacidade de usar
cd
, para que as respostas não precisem ser usadascd
. Revisado. Usandotput
e cores deman terminfo
:(Editado para usar o mais invulnerável, em
printf
vez do problemático,echo
que pode atuar nas seqüências de escape no texto.)fonte
Use
set -e
para definir o modo de saída com erro: se um comando simples retornar um status diferente de zero (indicando falha), o shell será encerrado.Cuidado que
set -e
nem sempre entra em ação. Os comandos nas posições de teste podem falhar (por exemplo,if failing_command
,failing_command || fallback
). Os comandos no subshell apenas levam à saída do subshell, não o pai: éset -e; (false); echo foo
exibidofoo
.Como alternativa, ou além disso, no bash (e ksh e zsh, mas não sh), você pode especificar um comando que será executado caso um comando retorne um status diferente de zero, com a
ERR
interceptação, por exemplotrap 'err=$?; echo >&2 "Exiting on error $err"; exit $err' ERR
. Observe que, em casos como(false); …
, a interceptação de ERR é executada no subshell, portanto, não pode causar a saída do pai.fonte
||
comportamento, que permite facilmente manipular erros sem usar armadilhas. Veja minha resposta . O que você acha desse método?ERR
pseudo-sinal seja suportado em todos os principais shells. Obrigado pela revisão! =)Para expandir a resposta do @Gilles :
De fato,
set -e
não funciona dentro de comandos se você usar o||
operador depois deles, mesmo se você executá-los em um subshell; por exemplo, isso não funcionaria:Mas
||
operador é necessário para impedir o retorno da função externa antes da limpeza.Há um pequeno truque que pode ser usado para corrigir isso: execute o comando interno em segundo plano e aguarde imediatamente por ele. O
wait
builtin retornará o código de saída do comando interno e agora você está usando||
depoiswait
, não a função interna, portanto,set -e
funciona corretamente dentro do último:Aqui está a função genérica que se baseia nessa idéia. Ele deve funcionar em todos os shells compatíveis com POSIX se você remover
local
palavras-chave, ou seja, substitua todoslocal x=y
por apenasx=y
:Exemplo de uso:
Executando o exemplo:
A única coisa que você precisa estar ciente ao usar esse método é que todas as modificações das variáveis do Shell feitas a partir do comando para o qual você passa
run
não serão propagadas para a função de chamada, porque o comando é executado em um subshell.fonte
Você não diz exatamente o que quer dizer com
catch
--- denuncie e continue; abortar processamento adicional?Como
cd
retorna um status diferente de zero em caso de falha, você pode:Você pode simplesmente sair com falha:
Ou ecoar sua própria mensagem e sair:
E / ou suprima o erro fornecido por
cd
na falha:Por padrão, os comandos devem colocar mensagens de erro no STDERR (descritor de arquivo 2). Assim
2>/dev/null
diz redirecionar STDERR para o "bit-bucket" conhecido por/dev/null
.(não esqueça de citar suas variáveis e marcar o final das opções para
cd
).fonte
Na verdade, no seu caso, eu diria que a lógica pode ser melhorada.
Em vez de cd e verifique se existe, verifique se existe e entre no diretório.
Mas se seu objetivo é silenciar os possíveis erros
cd -- "$1" 2>/dev/null
, isso fará com que você depure mais no futuro. Você pode verificar os sinalizadores de teste se em: Bash if documentation :fonte
$1
variável e falhará se essa variável contiver espaços em branco ou outros metacaracteres do shell. Ele também falha ao verificar se o usuário tem permissão paracd
entrar nele.