Como uso uma consulta If-Else com base no dia da semana?


10

Problema: preciso verificar se hoje é quinta-feira e executar ações diferentes com base no resultado dessa condição. Eu tentei duas abordagens diferentes:

Obtendo o nome do dia:

DAYOFWEEK=$(date +"%a")
echo DAYOFWEEK: $DAYOFWEEK
if ["$DAYOFWEEK" == "Thu"]; 
then   
   echo YES
else
    echo NO
fi

Obtendo o dia Num:

DAYOFWEEK=$(date +"%u")
echo DAYOFWEEK: $DAYOFWEEK

if ["$DAYOFWEEK" == 4]; 
then
   echo YES
else
   echo NO
fi

Nos dois casos, a saída é NÃO, mesmo que deva ser SIM. O que está errado?


1
Uma nota lateral: essas ;seriam necessárias se você tivesse thenna mesma linha que if. Nesse caso, eles são redundantes.
Manatwork

Respostas:


12

O problema está em branco em falta.

O código a seguir funcionará em shells cujo [comando interno aceita ==como um alias para =:

if [ "$DAYOFWEEK" == 4 ];  then    echo YES; else    echo NO; fi

Mas lembre-se (veja help testem bash):

  • ==não é mencionado oficialmente, você deve usar =para comparar seqüências
  • -eqdestina-se a testes aritméticos decimais (não fará diferença aqui, date +%umas faria, date +%dpor exemplo, quando se trata de comparar 04e 4que são numericamente iguais, mas lexicamente diferentes).

Eu preferiria:

 if [ "${DAYOFWEEK}" -eq 4 ];  then    echo YES; else    echo NO; fi

Geralmente, você deve preferir a abordagem do número do dia , porque ela tem menos dependência do local atual . No meu sistema, a saída de date +"%a"hoje é hoje Do.


3

Não negligencie casequal é a melhor maneira de fazer esse tipo de coisa:

Lembre-se também de que a saída de date +%adepende da localidade; portanto, se você espera os nomes em inglês, seu script deixará de funcionar quando chamado por um usuário francês ou coreano, por exemplo.

case $(LC_ALL=C date +%a) in
   (Mon) echo first day of the week;;
   (Thu) do-something;;
   (Sat|Sun) echo week-end;;
   (*) echo any other day;; # last ;; not necessary but doesn't harm
esac

Observe que acima é um dos casos raros em que $(...)isso não precisa ser citado (embora as aspas não sejam prejudiciais. O mesmo que em var="$(...)").


0

Na mesma idéia, eu uso o seguinte trecho de código para "desativar" um cron antes de uma hora escolhida.
É claro que prefiro modificar o próprio crontab ... se me forem concedidos os direitos necessários para :)

Aqui está um teste simples que interrompe um script do bash, a menos que estejamos à noite.

# Delay or restrict execution.
# Here, we quit unless hour is greater than (gt) 2 and (-a) lower than (lt) 7
# i.e. execution happens only at 3,4,5&6 o'clock.
if  /usr/bin/test `date '+%H'` -gt 2 -a `date '+%H'` -lt 7; then
  echo LETS_START_PROCESSING;
else
  exit;
fi

#Put job here

Por que usar em /usr/bin/testvez do [comando embutido do shell ?
Stéphane Chazelas

@ Stéphane Chazelas Eu não usei 3,4,5,6 porque não tenho acesso ao crontab. ( esta é a segunda linha do meu post :) Nossos servidores são gerenciados pelo Claranet e já perdemos uma semana de ticket-ping-pong para obter ... um cron funcionando (sem brincadeira). Portanto, evitamos estragar e reabrir tickets quando pudermos :) Por esse motivo, solicitamos uma tarefa cron de hora em hora em vez de diariamente, e até que todos os nossos testes sejam concluídos, será muito mais fácil não tocar na tarefa e adicione nossos controles no script executado.
Balmipour

Ah, ok, desculpe, pensei que você quis dizer que não tinha o direito de modificar o cronexecutável, em vez do crontab do usuário.
Stéphane Chazelas

@ Stéphane Chazelas Sobre a sintaxe do teste, eu preferi que [] ou [[]] porque tentei meu script em outro servidor primeiro, onde eu poderia usar o crontab. Depois de muitas surpresas com os crons, adquiri o hábito de usar o caminho absoluto nos crontabs o máximo possível. Pode-se dizer que torna os testes feios, e estará certo ... mas eu responderei que o teste do shell é sempre feio de qualquer maneira, e também estará certo ^^ O que importa para mim era principalmente ter uma resposta que funcionasse com um copiar / colar simples e incluir algumas explicações.
Balmipour

1
Observe que -aestá obsoleto em test. Standardly, você usaria: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](ou hour=`date +%H`se for necessário para ser compatível com o shell Bourne, que é Solaris 10 e unices SCO mais velhos e talvez alguns raros hoje em dia)
Stéphane Chazelas

0

Para parar o script no dia da semana, exclua apenas a linha do dia:

DAYOFWEEK=$(date +"%u")
echo "$DAYOFWEEK";
if [ "$DAYOFWEEK" == 1 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 2 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 3 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 4 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 5 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 6 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 7 ]; then exit; else echo; fi

Bem-vindo ao Unix SE! Não tenho certeza se entendi sua primeira linha corretamente. Não seria if [ "$DAYOFWEEK" -lt 7 ]melhor?
peterh - Restabelece Monica

-1

Primeiro, você deve citar a tarefa DAYOFWEEK = "$ (date +% u)"

E você precisa ter espaços em cada lado dos colchetes [e].

O ponto e vírgula no final da linha é redundante.


1
A citação não é necessária.
H.-Dirk Schmitt

Para expandir o comentário de @ H.-DirkSchmitt: a razão pela qual a citação não é necessária é que a saída não conterá espaços.
um CVn 07/03

@ MichaelKjörling: Não - nunca é necessário ;-) Experimente o exemplo:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt

@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $acom vários espaços entre os dígitos (StackExchange não permitirá que eu faça um simples copiar e colar, infelizmente).
a CVn 07/03

@ MichaelKjörling - consulte man bash "Se a substituição aparecer entre aspas duplas, a divisão de palavras e a expansão do nome do caminho não são executadas nos resultados." Portanto, no caso da pergunta e do exemplo "1 2 3" não há diferença.
H.-Dirk Schmitt
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.