Over a million developers have joined DZone.

A Rabbit Trail: Menu-Driven Bash Script - Part I

Today we are going to veer off Eli's previous path a bit, and look at Bash shell scripting.

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Introduction

We have been going merrily along our make-believe software journey about how what began as an afterthought, has turned into various delivered projects:  a component, several versions of web services, and several front-end web apps.

You can read all about that in these articles.

Today, however, we veer off momentarily into the world of Bash shell scripting.

As I have kept repeating within the articles, this software has grown organically.  We make changes and improvements as the need arises.  We don't pretend to see into the future.

If I remember correctly, two very opposite ends of the software development process could be:

Perhaps what might come to mind, when one thinks of Extreme Programming, is Pair-Programming, among other things.. but for my point here, I am referring to a heavy emphasis on refactoring.  It comes from the idea that we don't know what we need ahead of time, because it is new, or because circumstances change, etc.,  and so we add code only as much as to get the desired operation and no more.

NASA, on the other hand, really can't afford to do that, not as an overall principle.  Shooting off rockets and sending things off into space to explore, is very costly. So they do emphasize a lot of analysis up-front. They do try to think of every contingency that could possibly occur, etc.

I only bring up these two approaches, as a way to say that typically, what software developers find themselves doing, day-to-day, is closer to Extreme Programming, than it is to NASA's approaches.

But I am not just thinking in this way about how I approach a software project - it is also how I approach anything related to my job.

That brings us to this article.   I am lazy (let's hope all of us are) and finally got tired of having two Cygwin terminals up, one running MySQL, and the other with the shutdown command ready to recall and execute.

And it hit me that perhaps starting to script a menu-driven set of tools might not be a bad idea.

A Menu-Driven Bash Script: A Humble Beginning

This article will only be about what we need for today: to start and stop MySQL.

If we encounter other needs, we will add them as we go along in our software journey. We'll also improve how we wrote this initial script, and how pretty it might look, as we go along.

Today, just the bare minimum, because we need to continue with the main tasks at hand: to deliver the next release of the Shape Calculator Web App, converted to being a REST client. Please review the articles.

The Current Way We Run MySQL

During each of the current articles where we are exploring various Web Apps and Servcies, I have been running a local MySQL server in the following manner.

Image title

One window to start it, one to stop it.

Image title

Let's see if we can't change that to be simpler, quicker.

We Begin The Script

If you need to, please review this article that includes a section on Cygwin and your  /cygdrive/c/cygwin64//home/bin  directory.

I'm going to explain mostly via screenshots.

Image title

We started a new script file, my-tools.sh.  But when we try to run it, we get this weird error.  It means there's a tool we need to run: dos2unix.   But the standard minimum Cygwin install doesn't come with that.

It turns out that the steps of obtaining the dos2unix tool is very similar to the steps to install Cygwin.

Cygwin

I'm going to be brief here, there are plenty of articles about installing Cygwin.

First, you make sure all to exit all your current Cygwin windows, then:

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

Image title

You're ready now. Start a new Cygwin command window and:

Image title

Image title

(the above indicates auto-completion - using TAB)

Image title

Ok, we are ready now to really edit the menu-driven script.

Since we already hope to use this script in the future for other things, and we now want to manage the MySQL start/stop, that means we will have two menus to begin with:  the main_menu, and the mysql_menu.   Each will be a Bash function.

mysql_menu Function:

#######################################################################
function mysql_menu {
#######################################################################
while [ 1 ];
do
    echo "|=============================================|"
    echo "|             MySQL Menu                      |"
    echo "|=============================================|"
    echo "|1) Start MySQL                               |"
    echo "|2) Stop  MySQL                               |"
    echo "|=============================================|"
    echo "|b) Back                                      |"
    echo "|e) Exit This Tool                            |"
    echo "|=============================================|"

    menu_choice="";
    read -p "Please make a selection:" menu_choice

    case $menu_choice in
        1)
            ;;
        2)
            ;;
        b)
            break;
            ;;
        e)
            exit 0;
            ;;
        *)
            echo;echo;
            echo "Invalid selection: $menu_choice"
            echo;echo;
            ;;
    esac
done

return 0;
#######################################################################
} # end function mysql_menu
#######################################################################

main_menu:

#######################################################################
function main_menu {
#######################################################################
while [ 1 ];
do
    echo "|=============================================|"
    echo "|              Main Menu                      |"
    echo "|=============================================|"
    echo "|1) Start/Stop MySQL                          |"
    echo "|=============================================|"
    echo "|e) Exit                                      |"
    echo "|=============================================|"

    menu_choice="";
    read -p "Please make a selection:" menu_choice

    case $menu_choice in

        1)
            mysql_menu
            ;;
        e)
            break;
            ;;
        *)
            echo;echo;
            echo "Invalid selection: $menu_choice"
            echo;echo;
            ;;
    esac
done

return 0;

#######################################################################
} # end function main_menu
#######################################################################

Main Bash Script Execution Point:

At the end of the script file, we have this:


#######################################################################
#######################################################################
#######################################################################
# MAIN MENU - start of script
#######################################################################
#######################################################################
#######################################################################

main_menu;

exit 0;


We Test

Right now it doesn't really do anything with MySQL, but we want to just test out the basic menu-driven operation.

Image title

Looks good.

Add MySQL Stop

We'll do this one first since it is the easiest one of the two steps we need to add.

Image title

The above is easy because it runs and returns to the script menu as soon as mysqld is down.

However, if we do something similar to start MySQL, it never returns to our script.

Add MySQL Start

Image title

In the above statement, we are running the usual startup command, but in a separate Bash shell " $(...) " , and the really important piece is the singl ampersand & .  That means "run in the background".

If you run this, you'll see the usual MySQL startup log, and it would seem that the script is hung or that it didn't come back to the menu.  But just hit <ENTER> and you'll be back at the menu again.

Likewise, if you then select the shutdown option (#1), the mysqld server again outputs to the screen.... but if you hit <ENTER> again, you're back at the menu.

Complete Script File:

#!/usr/bin/bash


#######################################################################
function mysql_menu {
#######################################################################
while [ 1 ];
do
    echo "|=============================================|"
    echo "|             MySQL Menu                      |"
    echo "|=============================================|"
    echo "|1) Start MySQL                               |"
    echo "|2) Stop  MySQL                               |"
    echo "|=============================================|"
    echo "|b) Back                                      |"
    echo "|e) Exit This Tool                            |"
    echo "|=============================================|"

    menu_choice="";
    read -p "Please make a selection:" menu_choice

    case $menu_choice in
        1)
            $(mysqld --console) &
            ;;
        2)
            mysqladmin.exe -h 127.0.0.1 -u root shutdown
            ;;
        b)
            break;
            ;;
        e)
            exit 0;
            ;;
        *)
            echo;echo;
            echo "Invalid selection: $menu_choice"
            echo;echo;
            ;;
    esac
done

return 0;
#######################################################################
} # end function mysql_menu
#######################################################################

#######################################################################
function main_menu {
#######################################################################
while [ 1 ];
do
    echo "|=============================================|"
    echo "|              Main Menu                      |"
    echo "|=============================================|"
    echo "|1) Start/Stop MySQL                          |"
    echo "|=============================================|"
    echo "|e) Exit                                      |"
    echo "|=============================================|"

    menu_choice="";
    read -p "Please make a selection:" menu_choice

    case $menu_choice in

        1)
            mysql_menu
            ;;
        e)
            break;
            ;;
        *)
            echo;echo;
            echo "Invalid selection: $menu_choice"
            echo;echo;
            ;;
    esac
done

return 0;

#######################################################################
} # end function main_menu
#######################################################################




#######################################################################
#######################################################################
#######################################################################
# MAIN MENU - start of script
#######################################################################
#######################################################################
#######################################################################

main_menu;

exit 0;

Observation

The above script, as it now exists, expects those start and stop commands to work — that is — to be available via its PATH search.  It expects there to exist MySQL, etc.  There is no checking, no testing for failure.  We can add that sort of checking, or maybe even have it be smart enough to seek out possible MySQL commands (and their locations), and perhaps present a list from which we choose the correct one, and it then "remembers" our choices.

What Is Next

In order for this tool to really be helpful to us, as we move along in the Web Client / Web Services journey, there are at least two other improvements we could make.

  • Give it more database-related features such as showing databases, showing tables, descrbing tables, selecting data from a table

  • Graceful shutdown of the database when handling any CTRL-C (SIGINT) signal

  • Have the database server process appear in another (pop-up) window so that it's output wil not clutter our menu-driven tool

Stay Tuned!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:
cygwin ,bash ,script ,command line tools ,menu ,web dev

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}