Muita coisa, existe uma maneira melhor?

3

Eu tenho um script Bash que se parece com

#!/bin/bash
#
FECHA='date +%j'

if [ $FECHA -eq 40 ]
then
    echo "Esta semana le toca preparar el café a Osvaldo" | mail -s 'Café' [email protected]
    exit
elif [ $FECHA -eq 47 ]
then
    echo "Esta semana le toca preparar el café a Berenice" | mail -s 'Café' [email protected]
    exit
elif [ $FECHA -eq 54 ]
then
    echo "Esta semana le toca preparar el café a Nizaá" | mail -s 'Café' [email protected]
    exit
fi

que será executado, graças ao crontab, todas as segundas às 7 da manhã.

O script Bash real tem mais linhas, porque há mais pessoas envolvidas. Eu acho que funciona. Mas ... Existe uma maneira de fazer esse script com menos linhas?

Eu estava pensando: duas variáveis, uma para a pessoa que vai fazer o café e outra para a data e uma maneira de relacionar essas variáveis.

    
por murpholinox 04.02.2015 / 05:12

5 respostas

17

Acho que a construção case/esac se encaixa bem aqui.

#!/bin/bash

case "'date +%j'" in
  40) name=Osvaldo ;;
  47) name=Berenice ;;
  54) name=Nizaá ;;
  *) exit ;;
esac

echo "Esta semana le toca preparar el café a ${name}" \
   | mail -s 'Café' [email protected]

Observação: se a mesma pessoa precisar fazer café várias vezes, você poderá agregar testes com | :

case "'date +%j'" in
  12|23|40|49) name=Osvaldo ;;
  10|19|30|47) name=Berenice ;;
...
    
por 04.02.2015 / 09:17
6

Este é um bom caso para uma matriz. Aqui está um exemplo:

mapping=([40]='Osvaldo'
         [47]='Berenice'
         [54]='Nizaá')

echo "Esta semana le toca preparar el café a ${mapping[FECHA]}" | mail -s 'Café' [email protected]

Isso elimina totalmente as condicionais.

    
por 04.02.2015 / 05:41
1

Coloque os nomes em um arquivo de configuração, como coffee.txt:

040=Osvaldo
047=Berenice
054=Nizaá

Quando alguém está doente, demitido ou contratado, você não deseja alterar seu código:

name=$(grep "^$(date '+%j')=" coffee.txt | cut -d= -f2-)
echo "Esta semana le toca preparar el café a ${name}" \
   | mail -s 'Café' [email protected]
    
por 04.02.2015 / 18:16
0
set -- 40 Osvaldo 47 Bernice 54 Nizaá
[ "${FECHA#[54][074]}" = "${FECHA%"${FECHA#44}"}" ] &&
until    [ "$((${1#$FECHA}0&&$#))" -eq 0 ]         &&
         printf "${1+%s\n}" "Esta semana le toca preparar el café a $2"
do       shift 2; done
[ "$#" -gt 1 ] && mail -s 'Café' [email protected]
    
por 04.02.2015 / 09:11
0

Se cada bloco de código após uma condição if terminar em exit , você não precisará de elif ; basta encerrar o condicional com fi .

Eu também sou um grande fã de colocar o then na mesma linha que o if , o que torna o código mais curto na contagem de linhas e facilita (mais rápido) a leitura do IMHO. Então seu código se torna:

#!/bin/bash
#
FECHA='date +%j'

if [ $FECHA -eq 40 ]; then
    echo "Esta semana le toca preparar el café a Osvaldo" | mail -s 'Café' [email protected]
    exit
fi
if [ $FECHA -eq 47 ]; then
    echo "Esta semana le toca preparar el café a Berenice" | mail -s 'Café' [email protected]
    exit
fi
if [ $FECHA -eq 54 ]; then
    echo "Esta semana le toca preparar el café a Nizaá" | mail -s 'Café' [email protected]
    exit
fi

Além disso, neste caso, como o código é quase o mesmo em cada caso aqui, eu usaria a solução de Sam Hocevar.

    
por 04.02.2015 / 09:31