Esta pergunta apareceu em um questionário pré-entrevista e está me deixando louco. Alguém pode responder isso e me deixar à vontade? O questionário não tem referência a um shell específico, mas a descrição do trabalho é para um unix sa. novamente a questão é simplesmente ...
O que 'set -e' faz e por que pode ser considerado perigoso?
Respostas:
set -e
faz com que o shell saia se algum subcomando ou pipeline retornar um status diferente de zero.A resposta que o entrevistador provavelmente estava procurando é:
De http://www.debian.org/doc/debian-policy/ch-opersys.html 9.3.2 -
Esta é uma pergunta válida do ponto de vista do entrevistador, porque avalia os candidatos que trabalham com conhecimento de scripts e automação no nível do servidor
fonte
De
bash(1)
:Infelizmente, não sou criativo o suficiente para pensar por que isso seria perigoso, além de "o restante do script não será executado" ou "talvez possa mascarar problemas reais".
fonte
set
! Eu sempre acabo embuiltin(1)
. Obrigado.set
é encontrada emman 1 bash
?? e como alguém seria capaz de encontrar a-e
opção para aset
palavra - chave em uma página de manual tão grande? você não pode simplesmente/-e
procurar aquihelp set
Note-se que
set -e
pode ser ativado e desativado para várias seções de um script. Ele não precisa estar ativado para a execução do script inteiro. Pode até ser habilitado condicionalmente. Dito isto, eu nunca o uso, pois faço meu próprio tratamento de erros (ou não).Também é digno de nota isso na seção da página de manual do Bash no
trap
comando, que também descreve comoset -e
funciona sob determinadas circunstâncias.Portanto, existem algumas condições sob as quais um status diferente de zero não causará uma saída.
Eu acho que o perigo é não entender quando
set -e
entra em jogo e quando não e confiar nele incorretamente sob alguma suposição inválida.Consulte também o BashFAQ / 105 Por que set -e (ou set -o errexit ou armadilha ERR) não faz o que eu esperava?
fonte
Lembre-se de que este é um questionário para uma entrevista de emprego. As perguntas podem ter sido escritas pela equipe atual e podem estar erradas. Isso não é necessariamente ruim, e todo mundo comete erros, e as perguntas da entrevista geralmente ficam em um canto escuro sem revisão e só saem durante uma entrevista.
É perfeitamente possível que 'set -e' não faça nada que consideraríamos "perigoso". Mas o autor dessa pergunta pode acreditar erroneamente que 'set -e' é perigoso, devido à sua própria ignorância ou viés. Talvez eles tenham escrito um script de buggy, ele foi horrivelmente bombardeado, e eles pensaram erroneamente que 'set -e' era o culpado, quando na verdade eles deixaram de escrever uma verificação de erro adequada.
Eu participei de provavelmente 40 entrevistas de emprego nos últimos 2 anos, e os entrevistadores às vezes fazem perguntas erradas ou têm respostas erradas.
Ou talvez seja uma pergunta complicada, que seria ridícula, mas não totalmente inesperada.
Ou talvez seja uma boa explicação: http://www.mail-archive.com/[email protected]/msg473314.html
fonte
set -e
diz ao bash, em um script, para sair sempre que algo retornar um valor de retorno diferente de zero.pude ver como isso seria irritante e com bugs, não tenho certeza sobre perigos, a menos que você tenha aberto permissões para alguma coisa e antes que você possa restringi-las novamente, seu script morreu.
fonte
set -e
, pois , para mim, fala de preguiça de ignorar a verificação de erros em seus scripts ... então, lembre-se disso, também com esse empregador ... se eles o usarem muito, o que seus scripts parecer, que você terá, inevitavelmente, para manter ...set -e
finaliza o script se um código de saída diferente de zero for encontrado, exceto sob certas condições. Para resumir os perigos de seu uso em poucas palavras: não se comporta como as pessoas pensam.Na minha opinião, deve ser considerado um hack perigoso que continua a existir apenas para fins de compatibilidade. A
set -e
instrução não transforma o shell de uma linguagem que usa códigos de erro em uma linguagem que usa o fluxo de controle do tipo exceção, apenas tenta emular mal esse comportamento.Greg Wooledge tem muito a dizer sobre os perigos de
set -e
:set -e
)No segundo link, existem vários exemplos do comportamento não intuitivo e imprevisível de
set -e
.Alguns exemplos do comportamento não intuitivo de
set -e
(alguns extraídos do link wiki acima):let x++
retorna 0, que é tratado pelalet
palavra - chave como um valor falso e transformado em um código de saída diferente de zero.set -e
nota isso e termina silenciosamente o script.O procedimento acima funciona como esperado, imprimindo um aviso, se
/opt/foo
já existir.O que foi dito acima, apesar da única diferença de que uma única linha foi refatorada em uma função, terminará se
/opt/foo
não existir. Isso ocorre porque o fato de ter funcionado originalmente é uma exceção especial aoset -e
comportamento de. Quandoa && b
retorna diferente de zero, é ignorado porset -e
. No entanto, agora que é uma função, o código de saída da função é igual ao código de saída desse comando e a função que retorna diferente de zero encerra silenciosamente o script.O acima irá ler a matriz
config_vars
do arquivoconfig
. Como o autor pretende, ele termina com um erro seconfig
estiver faltando. Como o autor pode não pretender, ele termina silenciosamente seconfig
não terminar em uma nova linha. Seset -e
não fosse usado aqui,config_vars
conteria todas as linhas do arquivo, terminando ou não em uma nova linha.Usuários de texto sublime (e outros editores de texto que lidam com novas linhas incorretamente), tenha cuidado.
O autor aqui pode esperar razoavelmente que, se por algum motivo o usuário
$user
não existir, ogroups
comando falhará e o script será encerrado em vez de permitir que o usuário execute alguma tarefa não auditada. No entanto, nesse caso, aset -e
rescisão nunca entra em vigor. Se$user
não puder ser encontrado por algum motivo, em vez de encerrar o script, ashould_audit_user
função retornará dados incorretos como seset -e
não estivessem em vigor.Isso se aplica a qualquer função chamada da parte da condição de uma
if
instrução, não importa quão profundamente aninhada, não importa onde seja definida, não importa mesmo se você executarset -e
dentro dela novamente. O usoif
a qualquer momento desativa completamente o efeito deset -e
até que o bloco de condições seja totalmente executado. Se o autor não está ciente dessa armadilha ou não conhece toda a pilha de chamadas em todas as situações possíveis em que uma função pode ser chamada, ele escreverá um código de buggy e a falsa sensação de segurança fornecida porset -e
será pelo menos parcialmente culpa.Mesmo que o autor esteja totalmente ciente dessa armadilha, a solução alternativa é escrever o código da mesma maneira que se escreveria sem
set -e
, tornando efetivamente essa troca menos que inútil; não apenas o autor precisa escrever o código de tratamento manual de erros como seset -e
não estivesse em vigor, mas a presença deset -e
pode ter enganado-os a pensar que não precisam.Algumas desvantagens adicionais de
set -e
:let x++
acima, este não é o caso. Se o script morre inesperadamente, geralmente é silencioso, o que dificulta a depuração. Se o script não morrer e você esperava (veja o ponto anterior), você tem um bug mais sutil e insidioso em suas mãos.if
marcador de condição.set -e
ter sido ajustado entre essas versões.set -e
é uma questão controversa, e algumas pessoas cientes dos problemas que a cercam recomendam, enquanto outras recomendam tomar cuidado enquanto estiver ativo para conhecer as armadilhas. Existem muitos iniciantes em scripts de shell que recomendamset -e
em todos os scripts um exemplo geral para condições de erro, mas na vida real isso não funciona dessa maneira.set -e
não substitui a educação.fonte
Eu diria que é perigoso, porque você não controla mais o fluxo do seu script. O script pode terminar desde que qualquer um dos comandos que o script invoque retorne um valor diferente de zero. Portanto, tudo o que você precisa fazer é fazer algo que altere o comportamento ou a saída de qualquer um dos componentes e você poderá finalizar o script principal. Pode ser mais um problema de estilo, mas definitivamente tem consequências. E se o seu script principal deveria definir alguma sinalização e não o fez porque terminou mais cedo? Você acabaria culpando o resto do sistema se ele assumir que o sinalizador deveria estar lá ou trabalhar com um valor padrão ou antigo inesperado.
fonte
Como um exemplo mais concreto da resposta de @ Marcin que pessoalmente me mordeu, imagine que houvesse uma
rm foo/bar.txt
linha em algum lugar do seu script. Normalmente não é grande coisa sefoo/bar.txt
não existe realmente. No entanto, com oset -e
presente agora, seu script será encerrado mais cedo! Opafonte