script bash que lê a entrada do usuário e usa o comando “cal” para validar datas

script bash que lê a entrada do usuário e usa o comando “cal” para validar datas

Quero escrever um script que leia minha entrada (por exemplo, se meu script for chamado "check", então eu digitaria "check 9 4 1993" e essa entrada passaria pelo comando cal e verificaria no calendário se é uma data válida ou não).

Minha ideia abaixo é que se a entrada que passa pelo comando cal der um erro isso significará que não é uma data válida, e vice-versa se não houver erro então a data é válida. Sei que há algo terrivelmente errado com este rascunho (não consigo descobrir como fazer com que minha entrada passe pelo comando cal), mas apreciarei algumas sugestões. De qualquer forma, aqui está o rascunho:

#!/bin/bash

day=$1; month=$2; year=$3
day=$(echo "$day" | bc)
month=$(echo "$month" | bc)
year=$(echo "$year" | bc)

cal $day $ month $year 2> /dev/null
if [[$? -eq 0 ]]; then
   echo "This is a valid date"
else
   echo "This is an invalid date"
fi

Responder1

Em algumas distribuições Linux que verifiquei (por exemplo, Ubuntu 14.04), o pacote calvem do BSD e não do GNU Coreutils. A versão BSD parece não aceitar dias como parâmetro; apenas meses e anos. A versão do Ubuntu tem uma opção -H YYYY-MM-DD, mas isso não parece ajudar.

Em vez disso, eu usaria o dateutilitário. Assumindo o GNU Coreutils no Linux, acho que reescreveria seu script algo como:

#!/bin/bash

day=$((10#$1))
month=$((10#$2))
year=$((10#$3))

if date -d $year-$month-$day > /dev/null 2>&1; then
    # cal $month $year
    echo "This is a valid date"
else
    echo "This is an invalid date"
fi

Notas:

  • Estou usando o próprio shellexpansão aritméticapara validar entrada/remover zeros à esquerda, em vez de bifurcar um novo bcprocesso para cada parâmetro
  • estou usandoData GNUpara analisar a data de entrada
  • O comando date pode ser usado diretamente como ifexpressão condicional. iffunciona verificando os códigos de saída do processo. Normalmente, os executáveis [​​ou [[são usados, mas não há razão para que outros programas possam ser usados ​​se eles saírem com códigos de saída úteis
  • Não tenho certeza se você realmente queria a calsaída para datas corretas ou não. Se você fizer isso, simplesmente descomente a callinha.

Responder2

[[é na verdade um comando e, como outros comandos, você precisa de espaços em branco para separar seus argumentos:

if [[ $? -eq 0 ]]; then
# ...^

Responder3

Existe um espaço entre o seu dólar $e a sua monthvariável:

cal $day $ month $year 2> /dev/null

Deveria ser:

cal $day $month $year 2> /dev/null

Responder4

Se você digitar a data formatada como "%Y-%m-%d" ou "%m/%d/&Y" (por exemplo, 2020-11-29 ou 29/11/2020), poderá verificar a validade da data usando gnu data (gdate) assim:

gdate -d "$1" +'%Y-%m-%d' > /dev/null 2>&1  # don't display any output
status=$(echo $?)                           # get error code
if [[ $status = 1 ]]                        # if date is invalid
then
  { echo "This date doesn't exist. Enter valid date!"; exit 1; }
else
  ...

Espero ter acertado a pergunta e que isso ajude alguém. Claro que funcionou para mim :)

informação relacionada