3

I want to write a script that reads my input (for example if my script is called "check", then I would type "check 9 4 1993" and that input would go through the cal command and will check through the calendar whether it is a valid date or not).

My idea below is that if the input that goes through the cal command gives an error it will mean that it's not a valid date, and vice-versa if there's no error than the date is valid. I do realize there's something terribly wrong with this draft (I can't figure out how to make it so that my input will go through the cal command), but I will appreciate some suggestions. Here's the draft anyways:

#!/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
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
grinke
  • 31

4 Answers4

4

In some Linux distros that I have checked (e,g, Ubuntu 14.04), the packaged cal comes from BSD and not GNU Coreutils. The BSD version does not seem to accept days as a parameter; only months and years. The Ubuntu version does have a -H YYYY-MM-DD option, but that doesn't seem to help.

Instead I would use the date utility. Assuming the GNU Coreutils under Linux I think I would rewrite your script something like:

#!/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

Notes:

  • I am using the shell's own arithmetic expansion to validate input/remove leading zeros, instead of forking a new bc process for each parameter
  • I am using GNU date to parse the input date
  • The date command may be used directly as the if conditional expression. if works by checking process exit codes. Commonly the [ or [[ executables are used instead, but there is no reason other programs can be used if they exit with useful exit codes
  • I'm not sure if you actually wanted the cal output for correct dates or not. If you do, simply uncomment the cal line.
2

There is a space between your dollar $ and your month variable:

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

It should be:

cal $day $month $year 2> /dev/null
geedoubleya
  • 4,327
  • Damn, what a rookie mistake by me, thanks for noticing :)

    The script works as intended now, i have the right output.

    – grinke Oct 08 '14 at 17:16
2

[[ is actually a command, and like other commands you need whitespace to separate its arguments:

if [[ $? -eq 0 ]]; then
# ...^
glenn jackman
  • 85,964
0

If you type the date formatted as "%Y-%m-%d" or "%m/%d/&Y" (e.g. 2020-11-29 or 11/29/2020), you can check the date validity using gnu date (gdate) like this:

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
  ...

Hope I got the question right and that this helps somebody. Sure worked for me :)

gfidias
  • 1
  • 2