/ linux

Automating your Linux commands using bash because "Do Not Repeat Yourself".

It was normal Monday like every week. I got my laptop and pressed the Power button then I remembered that I had not Suspended(Hibernated) my machine but instead had shut it down last Friday to make sure the memory is not occupied and system runs faster .

Now the problem with shutting down is, I have to start eight different servers to get my Crossroad's apps up and running. Just for this reason ,I refrained from Shutting Down my machine every day and instead chose to Suspend which would save me from hitting numerous keyboard keys and do the same things, to start these servers every time I switched off my machine.

First of all, I had to open the terminal and then hit Ctrl+Tab+N eight times or some times more to open eight terminal tabs for each of the servers and apps. And then I had to individually change the directory for each file location and then type rails command or ember commands in each file location to make sure all the apps are running .

But as they say 'Laziness Is The Mother Of Invention', I decided to take a one time pain of automating all these things by taking advantage of Linux commands and a bash file, so that I don't have to go through the same commands each time I switched off my machine or update forced me restart my machine .

Initially I was under impression that my web search would give me the solution right on the first page if not the first link. But it wasn't that easy. It was tough to find few of the commands especially the one to open new tabs in same terminal Window.

This is highly specific for Linux and might not work on Windows and Mac.

The command I am going to use first opens a new tab in same terminal and then types the desired command in the terminal and executes them one by one.In order to open multiple processes or servers you need to add the same commands again at the bottom by changing the quoted command.
So following are the commands that I used to automate the server start-up.

WID= xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"| awk '{print $5}';
xdotool windowfocus $WID;
xdotool key ctrl+shift+t
sleep 1;
xdotool type --delay 1 --clearmodifiers "cd ~/Kiprosh_Goodcity/Goodcity/stockit;   source $HOME/.rvm/scripts/rvm;   rvm use 1.8.7-p370; bundle install;  rails -p 4000;";

Breaking each line of the above commands we get:
WID= xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"| awk '{print $5}';
This does the job of getting the Current Window ID and saves it in the variable WID.

xdotool windowfocus $WID;

Xdotool is used to for things like mouse press , keyboard button press or even Window focusing. So here we are trying to focus on the current Window first so that whatever we do happens in the same Window instead of new Window.

xdotool key ctrl+shift+t

This command just hits keys ctrl+shift+t from keyboard automatically. Which is used to open a new tab in same Window.

sleep 1

This causes the commands to delay by 1 second because mouse or keyboard events sometimes takes a bit longer to execute. So here our command execution process stops for a second just to ensure that the desired button is pressed and only then next commands are executed.

xdotool type --delay 1 --clearmodifiers "cd ~/Kiprosh_Goodcity/Goodcity/stockit;source $HOME/.rvm/scripts/rvm; rvm use 1.8.7-p370; bundle install; rails -p 4000";

This command types the desired commands on terminal that we usually type to start a server or to perform some monotonous task . Here first of all we are changing the directory to my Project directory and then setting HOME path variable to rvm so that I could use rvm 1.8.7 which is not my global version of rails. Then finally, starting the Rails server after installing bundle.

You need to put all your commands between the quotes separated by semi-colon.

Once we know what commands we really need to run we can proceed to create a bash file and then insert these commands in it.

  1. First of all you need to create a bash file. Create a new file and write following at the top(must be the first line of file)


    Now save it with a some name and .sh extension.
  2. Once you do that, you just need to add the above commands to the file after our first line.
  3. That's it, now you are ready to run your automated command it by typing ./filename.sh on terminal by going to the directory where you saved the bash file.

Suppose I need to run my Ember server along with Rails server so I need to write the bash file as follows:

#to start rails server
WID= xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"| awk '{print $5}';
xdotool windowfocus $WID;
xdotool key ctrl+shift+t
sleep 1;
xdotool type --delay 1 --clearmodifiers "cd ~/Kiprosh_Goodcity/Goodcity/stockit; source $HOME/.rvm/scripts/rvm; rvm use 1.8.7-p370; bundle install; rails -p 4000;";

#to start ember server
WID= xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"| awk '{print $5}';
xdotool windowfocus $WID;
xdotool key ctrl+shift+t
sleep 1; 
xdotool type --delay 1 --clearmodifiers "cd ~/Kiprosh_Goodcity/Goodcity/stock.goodcity; npm start;";

Now when I type startserver.sh on terminal both these servers get up and running on two new tabs without having to change the directory and type the commands each time.

That's was a nice way of being lazy. Maybe you should too try be one :P