July 11, 2009

Gentle introduction to “friendly” Linux shell

For this small tutorial I used Ubuntu 9.04 – so it is Gnome and things attempted here should work on any other distro which is using Gnome, but I can not guarantee that. Yes, I will use zenity, but not right away.

Shell on Linux system is very powerful and through time it was made even more powerful with number of utilities and packages which one can call from shell.

To do “Hello World!” click on Applications → Accessories → Terminal. When terminal window is open it will present you with prompt where you can type in command to be executed. We want to print “Hello World!” and here it is:

echo "Hello World!"

And that will result in failure.

bash: !": event not found

Then one is tempted to escape exclamation sign, like this:

echo "Hello World!"

Which results in lesser failure:

Hello World!

At this stage people are quite inclined towards leaving shell for beter times and sticking with point and click world. Some will go and report the bug as well.

What is the problem here?

Due to POSIX spec '!' cannot be escaped within double quotes. Throwing away POSIX compliance is out of question, so what do we do? Single quotes will work well or appending '!' outside of double quotes, like this:

echo "Hello World"!

That will finally print the desired Hello World! Please note that if we decided to create script with the following content:

#!/bin/bash

echo "Hello World!"

we would not have any problems with '!'.

BTW to execute script one must change permissions on it. Open gedit copy, paste the code and save it as hello. Be sure that it contains only
new line and not evil
new line. Go to the directory where it is saved, right click and from context menu select Properties. The third tab named Permissions contains check box with text 'Allow executing file as program'. Tick that check box and close thedialog – script is now executable. Go back to terminal and cd to where hello is located and finally type into terminal:

./hello

That will execute script. That works because we are not in interactive mode. To achieve the same from Terminal, do:

cd PATH_TO_HELLO_DIR

chmod a+x hello

./hello

OK back to '!' and interactive shell problem. Shell which we are using is called bash or Bourne-Again Shell and it remembers commands which are issued to it in interactive mode. If we want to repeat some command, we use up arrow on keyboard, in terminal executed commands will appear one at the time as we hit arrow button. To see all executed commands we can type history into terminal and hit enter. That will print something like this:

… omitted to save space ...

299 cd Documents/

300 chmod a+x hello

301 ./hello

302 history

Now to repeat command 301 we can do:

!301

./hello

Hello World!

Bellow is the result, it first prints and after that executes the command. Now there is a pile of useful additions to it, for example:

!.:p

Find freshest command starting with dot and just print it without executing it. Now we know how to print 'Hello World!' and why '!' may give us hard time. Next time we will try to read users input and add some GUI to our shell scripts.

Click Here!