verificar erros ... ou não !!

1. verificar erros ... ou não !!

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 27/04/2018 - 21:52h

Pessoas ... tenho no script uma pancada de "cp" ... preciso gerar 2 "echo's"
1 - Operações concluídas com sucesso
2 - Operações concluídas com erros

to meio sem saber como criar esse IF com essa pancada de CP .. alguma idéia ?

A principio eu pensei em caso de erro, ir somando 1 em um arquivo temp, no final eu faço o IF do temp, mas não sei se seria o melhor caminho.




  


2. Re: verificar erros ... ou não !!


oxidante

(usa Debian)

Enviado em 27/04/2018 - 22:49h

Podes salvar a contagem de erros numa variável em vez de arquivo...

nerro=0
cp a1 a2 || nerro=$(($nerro+1))
cp a2 a3 || nerro=$(($nerro+1))

if [ $nerro -gt 0 ]
then
echo "Deu erro!"
else
echo echo "Sucesso!"
fi





3. Re: verificar erros ... ou não !!

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 27/04/2018 - 23:09h

oxidante escreveu:

Podes salvar a contagem de erros numa variável em vez de arquivo...

nerro=0
cp a1 a2 || nerro=$(($nerro+1))
cp a2 a3 || nerro=$(($nerro+1))

if [[ $nerro -gt 0 ]]
then
echo "Deu erro!"
else
echo echo "Sucesso!"
fi




eu fiz exatamente como vc postou ... eu fiz o tópico dizendo em salvar em arquivo porém fiz salvando na variável ... só não fiz esse pipes duplos ... na moral nem sei pra que servem !!!

EDIT: pra q os colchetes duplicados no if ????

------------------------------------------| Linux User #621728 |-----------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------| Linux User #621728 |-----------------------------------------



4. Re: verificar erros ... ou não !!


oxidante

(usa Debian)

Enviado em 28/04/2018 - 00:14h

Essas 2 barras verticais (||) não têm a função de pipe. Elas servem para executar múltiplos comandos com base numa condição, neste caso, na condição "OR" (em português: OU). Cada comando após o primeiro só será executado quando seu antecessor retornar o valor "falso". No Bash, qdo ocorre um erro num programa ou comando, este retorna um valor, que geralmente corresponde aos valores verdadeiro (1, sucesso) ou falso (0, erro).

Quando fazemos:
cp arq1 arq2 || echo "Erro ao copiar" 

o script irá executar o comando "echo" somente se o "cp" retornar falso, ou seja, se der um erro. Caso contrário, ignora o "echo" e passa para a próxima instrução do script.

Essa funcionalidade é conhecida como "Listas" no Bash, que incluem a lista OR e a lista AND.
A lista AND funciona da mesma forma, mas só irá executar os comandos seguintes se o antecessor retornar verdadeiro, ou seja, se for sucedido (sem erro).

Caso queira compreender melhor na prática essa funcionalidade, faça as instruções abaixo no terminal e tente responder às questões:

Fato: arq1 não existe! Por que então o terceiro comando da lista ("echo DEF") não é executado no comando abaixo?
cp arq1 arq2 || echo ABC || echo DEF 

E na instrução a seguir, pq o terceiro comando (echo DEF) não é executado?
echo ABC && cp arq1 arq2 && echo DEF 

Não sei se deu pra entender, meu vocabulário em shell ainda é bem básico. hehe


5. Re: verificar erros ... ou não !!


oxidante

(usa Debian)

Enviado em 28/04/2018 - 00:17h

Mauriciodez escreveu:
EDIT: pra q os colchetes duplicados no if ????

Não precisa dos 2 colchetes, falha minha. Comentário atualizado.


6. Re: verificar erros ... ou não !!

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 28/04/2018 - 00:39h

Que || e && é OR e AND eu tenho conhecimento ... só não comprendi a lógica da parada ( se é q tem lógica )

então se eu tenho só uma condição, eu não preciso fazer um IF ... interessante !!!


[ 1 -eq 2 ] || echo "errado"
[ 1 -eq 1 ] && echo "certo"


------------------------------------------| Linux User #621728 |-----------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------| Linux User #621728 |-----------------------------------------



7. Re: verificar erros ... ou não !!

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 28/04/2018 - 00:47h

oxidante escreveu:
Fato: arq1 não existe! Por que então o terceiro comando da lista ("echo DEF") não é executado no comando abaixo?
cp arq1 arq2 || echo ABC || echo DEF 

(echo DEF) não executou pq (echo ABC) retornou 1


oxidante escreveu:
E na instrução a seguir, pq o terceiro comando (echo DEF) não é executado?
echo ABC && cp arq1 arq2 && echo DEF 

(echo DEF) não executou pq (cp arq1 arq2) retornou 0


É isso ???

------------------------------------------| Linux User #621728 |-----------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------| Linux User #621728 |-----------------------------------------



8. Re: verificar erros ... ou não !!

Paulo
paulo1205

(usa Ubuntu)

Enviado em 29/04/2018 - 06:19h

Uma forma mais compacta e mais eficiente de reescrever a primeira resposta de nosso colega oxidante seria a seguinte.

nerro=0
cp a1 a2 || (( ++nerro ))
cp a2 a3 || (( ++nerro ))

if (( nerro )); then
echo "Deu erro!"
else
echo echo "Sucesso!"
fi



9. Re: verificar erros ... ou não !!

Paulo
paulo1205

(usa Ubuntu)

Enviado em 29/04/2018 - 10:22h

Mauriciodez escreveu:

EDIT: pra q os colchetes duplicados no if ????


Eles são uma forma mais eficiente de fazer testes, garantindo que o shell não vai chamar um comando externo para testar o que você quer testar.

Permita-me contar uma historinha.

O shell tradicional não tinha um mecanismo próprio de avaliar expressões relacionais nem aritméticas, e mesmo expressões booleanas eram limitadas a situações em que os valores testados eram o código de retorno resultante da execução de um comando (comandos bem sucedidos, com código de retorno igual a zero, correspondiam ao valor lógico verdadeiro, e comandos com código de retorno diferente de zero eram entendidos como tendo falhado, com valor lógico falso). O próprio comando if se limitava apenas a executar um comando e ver se ele executava com sucesso com falha.

Para conseguir testar expressões relacionais e para avaliar expressões aritméticas, era preciso recorrer a comandos externos. O comando test recebia uma expressão lógica ou relacional a ser testada, e devolvia código de retorno correspondente ao resultado do teste (zero se verdadeiro, diferente de zero se falso). Para expressões aritméticas, o comando externo se chamava expr, e sua saída era textual, impressa na saída padrão, de modo que se um script quisesse usá-la para fazer uma atribuição de valor a uma variável, ele tinha de redirecionar a saída, por meio da execução entre dois sinais de acento grave ("`").

Sendo assim, no shell tradicional, o primeiro script mostrado por nosso colega oxidante teria de ser reescrito mais ou menos da seguinte maneira.

nerro=0
cp -p a1 b1 || nerro=`expr $nerro + 1`
cp -p a2 b2 || nerro=`expr $nerro + 1`
if test "$nerro" -ne 0; then
echo "Houve $nerro erro(s)."
else
echo "Cópia com sucesso."
fi


Lá pelas tantas, alguém deve ter achado que escrever "if test expressão" era muito feio ou chato, e resolveu rebatizar o comando test como [, a fim de permitir escrever expressões na forma "if [ expressão ]". De fato, isso é visualmente mais confortável, mas, no fundo, pouca coisa mudou. A sintaxe aparente ficou mais interessante, mas [ continuou sendo um comando externo (veja que deve existir, na sua máquina, um arquivo chamado /bin/[, que é um segundo nome do arquivo /bin/test). Por ser um comando externo, ele continuou tendo os seguintes inconvenientes:

  • custo de execução, tanto em tempo quanto em recursos, por ter de criar um processo novo, chamar um executável, aguardar sua execução, e fazer a limpeza dos recursos depois de ele ter terminado;
  • por ser um comando externo, ele só seria executado se a variável de ambiente PATH contivesse o diretório /bin (ou /usr/bin, dependendo do sistema; essa dependência, aliás, é outro sintoma de inconveniência);
  • se, por algum acidente, o arquivo /bin/[ tivesse sido apagado, os scripts que o invocassem deixariam de conseguir efetuar seus testes relacionais;
  • um problema de segurança podia acontecer: se o script não tivesse cuidado, um valor indevido na variável PATH poderia fazer com que um outro arquivo chamado [, hospedado num outro diretório, fosse executado em lugar do /bin/[;
  • a sintaxe era mesmo apenas aparente: o fechamento dos colchetes, que ajudava nessa suposta sintaxe, não era exigido pelo shell, mas sim pelo próprio comando, que acabava tendo de ter dois comportamentos diferentes, dependendo de se tivesse sido invocado como [ ou como test.

Quando se criou o Korn-Shell, com a esperança de que ele viesse a substituir o shell tradicional, tentou-se tratar pelo menos uma parte dos problemas acima, mas de um modo tão conservador que acabou surtindo menos efeito do que o que se pretendia. O ksh introduziu novas formas de efetuar avaliações lógicas e aritméticas sem usar comandos externos, por meio de comandos internos como [[ ... ]] e (( ... )), e havia a indicação de que essas formas deveriam ser preferidas em relação ao uso dos comandos externos test/[ e expr, mas não se forçou que isso fosse feito, nem alterou o comportamento do shell quando esses comandos externos apareciam: eles continuavam sendo executados como comandos externos. Além disso, os fabricantes temiam incompatibilidades do novo shell com scripts antigos, e continuaram distribuindo o shell tradicional como /bin/sh, com o Korn-Shell tendo de ser explicitamente referenciado como [/bin/ksh, o que atrapalhou ainda mais sua ampla adoção. E, para piorar ainda mais, a batalha legal entre a AT&T de um lado e a UCB (University of California, Berkeley) e BSDI (Berkeley Software Design, Inc.) de outro fez com que o mundo open source não pudesse ter acesso ao Korn-Shell durante muitos anos, tendo de usar ou o shell tradicional ou o C-Shell do BSD (um shell, à época, inovador em diversos aspectos, mas com vários inconvenientes quando usado para fazer scripts, a ponto de estar quase abandonado hoje em dia).

Com o surgimento do Bash e sua ampla adoção, o mundo open source teve uma nova oportunidade de lidar com as questões desempenho e de compatibilidade com o shell tradicional. O Bash adotou as novas formas introduzidas pelo Korn-Shell, mas deu um passo além, incorporando como comandos internos as formas tradicionais de test e [. Desse modo, esperava-se que scripts escritos com a sintaxe tradicional pudessem ganhar desempenho quando executados pelo Bash (especialmente em sistemas que tivessem a ousadia de fazer do Bash seu shell padrão, hospedado como /bin/sh, como é o caso do Red Hat e afins) mas continuassem funcionando num shell tradicional, até porque muitos sistemas continuavam e continuam usando shells menores e supostamente mais leves como padrão em /bin/sh (Debian e derivados, todos os BSDs, UNIXes comerciais etc.). Além do mais, mesmo quando executando sobre o Bash, as versões internas dos comandos tradicionais podem ser desabilitadas por meio do comando enable com opção -n.

A versão com dois colchetes, bem como os dois parênteses para operações aritméticas, são exclusivamente internas, e não podem ser desabilitadas. São, portanto, mais seguras.

Na prática, porém, problemas de compatibilidade acabam existindo também com o Bash. Mesmo que se desabilitem as versões internas dos comandos aqui discutidos, é muito tentador usar outros recursos do Bash que não existem no shell tradicional, tais como mais e melhores operações com strings, mais e melhores opções de expansões e de redirecionamentos, arrays e arrays associativos, melhor suporte a locales e muitos outros. Pelo aspecto de segurança, desabilitar as versões internas dos comandos seria obviamente pouco interessante, mas seria relativamente difícil impedir que um eventual atacante conseguisse provocar essa desabilitação.

Assim sendo, minha recomendação pessoal é que, se o seu script tiver que usar algum recurso do Bash, você explicite isso na primeira linha (i.e. usando “#/bin/bash”, em vez de ”#!/bin/sh”), e prefira usar todos os recursos que o tornam mais seguro, incluindo usar “[[ ... ]]” em lugar de “[ ... ]”.

Em tempo: eu estou ciente de que existe uma diferença entre os dois testadores, referente ao uso de comparadores de strings, pois o de test/[ usa sempre a ordenação do ASCII, ao passo que [[ usa a locale corrente. Mas isso é muito fácil de contornar, bastando mudar a locale corrente para “C”, antes de invocar a comparação com [[.


10. Re: verificar erros ... ou não !!

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 30/04/2018 - 15:10h

Valew Paulo ... ainda não tive tempo para ler ... assim q der uma lida eu te dou um retorno !!!

Abçs.

------------------------------------------| Linux User #621728 |-----------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------| Linux User #621728 |-----------------------------------------







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts