5 min read

I'm a kind of champion when it comes to creating some problems - maybe best od stupid problems - and today i was working with on our new server with some friends and we couldn't know when someone needs the server for an update or somethig like that. So we decided to create an agenda to book the server.

Requirements

To follow this tutorial, you will need:

  • A computer with a Bash shell
  • An editor of your choice
  • A bit of patience and motivation

Step 1 - Define the features

With the agenda, we must be able to:

  • Add an entry
  • Delete an entry
  • Show all of our entries
  • Nice presentation ( Because it's the shell )
  • Store all the data somewhere

Now that we have defined the features, let's code this.

Step 2 - Define our database

It's a personal agenda, and I don't want it to be on the internet, for now, so I choose to use a CSV file so I can open it with excel or open office. Let's call it db.csv

At the top of our file, define a variable and assign the name of our file

my_db_file=db.csv

Step 3 - Create a function to add entries

First of all, we ask the user to input data, then we store it in our database.

And we need to make sure that the user has entered data.

add()
{
  clear
  echo -e "\nInformations about the new entry"
  while [ -z "$_title" ]
  do 
    read -p "Title --> " _title
  done
  while [ -z "$_date" ]
  do 
    read -p "Date (AAAAMMJJ) --> " _date
  done
  while [ -z "$_hour" ]
  do 
    read -p "Hour (HH:MM) --> " _hour
  done
  echo "$_title;$_date;$_hour" >> "$my_db_file"
  unset _title
  unset _date
  unset _hour
  clear
}

Let's break this down.

We clear the console ( i don't think that I'm the only one who hates seeing old command results ) with clear

We display a nice message to the user asking him to Enter the pieces of information with the command echo. The flag -e is used to enable interpretation of backslash escape sequences.

We ask the user for different inputs with the command read. The flag -p is used to display a prompt.

To make sure the user has typed something, we put our prompt in a loop that will ask the user for input while the variable is empty. To do so, we use the while command with a test. To test if a variable is empty, we use the flag -z.

After that, we write append data a the end of the file with the echo command. We need to add a separator that will be for me the CSV's one: our dear semicolon. And we write to a file with echo command when we add the superior sign before the file we want to write in.

With 2 superior signs, it creates our file when it doesn't exist and it appends to the end of the file if it exists.

With 1 superior sign, it creates the destination file if it doesn't exist and overwrite the destination file if it exists.

echo "foobar" >> file.txt will create or append if exists.

To finish with this function, we destroy the variables with unset so when the user will add a new entry, it will fall through the loops.

Then we clear the console :)

Step 4 - Create a function to consult entries

This function is called just after we start our script. It's the one that reads and displays the data from our database.

consult()
{
  if [ -f "$my_db_file" ];then
    i=1
    while IFS=";" read -r title date hour
    do
        echo -e "$i\t$title\t$date\t$hour"
        i=$(($i+1))
    done < "$my_db_file"
  else
    echo -e "Database file not found, add an entry to create it.\n"
  fi
}

There we use an if statement to check if the file exists else we would get an error. In case the file doesn't exist, we display a nice message to the user. To test if a file exists, we use the flag -f in the if statement.

Now we initialize a counter ( we will use it later to delete entries ) that we will increment after each line.

Then now we refine the IFS ( Internal Field Separator ). In my case it is the semicolon. It's is used for word splitting after expansion and to split lines into words with the read builtin command.

After that, we define the variables that will receive the file read output.

In the while loop, we display the entry line as id, the title, the date, and the hour. At the end of the while statement, we give the database file as input. We do that to specify the file we want the script to read.

Step 5 - Create a function to delete entries

This one is a little bit tricky

delete()
{
  clear
  echo -e "\nEnter the id of the entry to delete"
  while [ -z "$_entry_id" ]
  do
    read -p "Id --> " _entry_id
  done
  read -p "Are you sure? [ Y or y to confirm / Any other key to abort ] " _confirm
  if [ "$_confirm" = "Y" ] || [ "$_confirm" = "y" ]; then
    _entry_id+="d"
    sed -i".bak" $_entry_id "$my_db_file"
  fi
  unset _entry_id
  unset _cofnirm
  clear
}

Again we ask for an input that will be the entry id that matches the entry's line number.

To delete the entry in the file, we will use sed, the syntax to do what we want to do is

sed -i".bak" [line number starting from 1]d [file name]

The flag -i is used to backup our file, directly next to it we specify.

The d after the line number is to specify that we want to delete a line

And the last parameter is the file name

We don't forget to destroy our variables.

Step 6 - Create the main menu to wrap everything up

On the menu, we should print the actual date and hour, the different options, and make all of this a little bit nice.

while true 
do
    clear
    actual_date=$(date +%d-%m-%Y)
    actual_hour=$(date +%H:%M)
    echo -e "Today: $actual_date $actual_hour\n**************************\nList of entries\nid\tTitle\tDate and Hour\n"
    consult
    echo -e "**************************\nMenu\n1- Add an etry\n2- Delete an entry\n0- Exit\nEnter your selection"
    read -p "--> " _selection
    case $_selection in
        1) add ;;
        2) delete ;;
        0) clear
           echo "Press enter to exit"
           read
           clear
           exit;;
        *) echo "Unknown choice";;
    esac
done
exit

We put an infinite while loop so we ask the user for its choice until option 0 is selected.

In the loop we define our main menu. First, we get the actual date and hour, then we print them then, we print a helper to identify the fields that will be printed. After that, we call the consult function and print the options.

After reading the user input we use a switch statement on the variable.

For each value, there is a function invoked.

And it is finished

Conclusion

We now have our personal agenda in our shell. Enjoy it.

The source code is available on GitHub.

Enjoying our content? share with a friend.
Any question? Any suggestion? Tell me down here 👇

Hermann

Hermann

A geek and a big dreamer.

https://itishermann.me Limoges, France