Learning the bash shell, continued

i-30a1e0366512a8ac50ae2cf969f02d73-learning_bash_shell.jpgI started this discussion a while back, and not it is time to continue it.

The Bourne Again Shell, bash, is the default command-line shell in Ubuntu and many *nix (Unix, Linux, etc.) systems. You can think of the shell as the most direct way to get into your operating system, and you can think of shell scripts (‘programs’ in essence) as macros that can automate computerized tasks.

For the present purposes, I’m discussing the book Learning the bash Shell (In a Nutshell (O’Reilly)) although the examples I’m providing are not necessarily from this text.

How to make a script

You make a script by making a text file, putting it in the right place on your computer with a correct name, throwing in a shebang line, writing correct bash code, changing permission on the script to be executable. This sounds like a lot of steps to go through, but once you’ve done it a few dozen times it becomes second nature.

Making the text file

Use a regular no-frills text editor. If you are using Ubuntu with Gnome, “gedit” is probably the way to go. If you are a masochist, use vi, ed, or emacs. Don’t use a word processor.

Put the file in the right place and give it a good name

The scripts you write should be in your home directory, so that when you upgrade your system, leaving your home directory intact (which is how you should always do upgrades) your work will still be there. Most likely there is a directory in home called “bin” and it is already on your shell’s path.

The path is the list of directories your shell searches for commands when one is executed. If there are multiple commands on your system with the same name, there is a certain order in which the shell searches for the command. This is a little complicated, which is why I’m connecting this post with a book chock full of details. Read the book.

You should avoid naming the script with a name that is already used for an existing command or program on your system. An obvious way to find out if a name is already in use is to run it. If you type a name in and it is in use, you can tell because either something happens, or nothing happens. If you type in a name and it is not in use, you get an error.

greg@greg-desktop:~/bin$ test
greg@greg-desktop:~/bin$ blfnig
bash: blfnig: command not found

The first try, with ‘test’ resulted in nothing. Nothing happening is one way the shell tells you that the command exists, and in this case, ran just fine. In contrast, ‘blfnig’ resulted in an error. So ‘blfnig’ could be a good name for a shell script you may right. Except it isn’t because it does not convey any meaning.

I’m going to write a script to test out script writing, but I can’t call it ‘test’ because there appears to already be such a command. so I’ll call it ‘testscript’

So I’ve got a text editor open, and now I need to put in the shebang line.

In bash, the symbol # is used to start a comment. But if you put this as the first line in your script, followed by the symbol ! and follow that with the path to where the bash shell itself (the program) lives, then you’ve got a shebang line. This line tells the system that this script uses this shell (bash) to run it.

I’m also going to make my program simple. It will simply say hello. To the world. As usual.

#!/bin/bash
#
# A test script

echo hello world

Now, I save that file in the /bin directory. I can check to see if it is there by moving to that directory and running a file listing command.


greg@greg-desktop:~$ cd bin
greg@greg-desktop:~/bin$ ls
blogroll_java.txt blogroll_m2java.sh~ googcalc testscript~ test.sh~
blogroll_m2java fixblogroll now testscript.sh
blogroll_m2java~ fixblogroll.sh now~ testscript.sh~
blogroll_m2java.sh fixblogroll.sh~ testscript test.sh
greg@greg-desktop:~/bin$

Notice that it is there. Notice also that I don’t have a lot of other scripts here (this is not my main playing-around computer). Had there been a lot of stuff in here, I may have given the ls command some help to help me find what I’m looking for

greg@greg-desktop:~/bin$ ls test*
testscript testscript~
greg@greg-desktop:~/bin$

The extra ‘testscript’ with the squiggly thing must be something my text editor put there.

Make the script executable

Each file on a linux system has a number of attributes indicating ownership and permissions. By default, a file created with a text editor will not have “executable” permission. This does not mean you can’t execute it, but to do so you need to do special mojo. It is easier to simply change the permission.

Assuming you are you using your account on your own computer, all you need to do is to run the change mode command, like this:

chmod +x testscript

What is this arcanery, with the ‘plus-x’ thing? Read the book. It will work. Now, I can run my script using the name of the script and nothing else.

greg@greg-desktop:~$ testscript
hello world
greg@greg-desktop:~$

Notice that when you were not looking I changed back to my home directory. bash finds the script because the /bin directory is in my path.

I am nothing close to an expert on this [get yer troll bait here!] and I have to say that what I do know about this topic I did not really learn from “Learning the Bash Shell.” I learned some basic Unix stuff from using Unix computers years ago, and I’ve wallowed through over the last few years using various cheat sheets on the web and following examples set by others. A few months ago I decided to learn more about bash, and read “Classic Shell Scripting” … a book I’ll discuss in a later post. But more recently I realized that I had fallen into the trap of having very uneven knowledge and getting stuck in places I really should not be stuck. So I picked up “Learning the bash Shell” to help fill in those gaps. The book assumes a fair amount of familiarity with computers and a strong resolve, and by the time you get to the end you may find yourself skimming chapters that are more about system administration tasks that a single user machine does not necessarily require.

But it is a good way to get beyond mere fiddling around, and I recommend it.

Now, I’m about to publish this post, but since I started writing it some time ago, the “entry date” is way in the past. So I need a correctly formatted date giving me the current time in New York, where the Scienceblogs.com mother ship lives.

So could open a shell and enter:

date -d '+1 hour' '+%Y-%m-%d %H:%M:%S'

to get a properly formatted Entry Date for the Movable Type interface…

… or, since I do this all the time, maybe I should write a script that does this automatically….

Comments

  1. #1 Matt Platte
    March 19, 2008

    s/chmode/chmod/g

    I find transcripts of shell sessions way, way harder to decipher than when the command-and-response is presented in real time. But then I’m old and easily bored/distracted.

  2. #2 Corey
    March 19, 2008

    I wish they taught this stuff in grade school. I’m taking a course in bioinformatics, and time we could have spent learning bioinformatics we had to spend learning what you outlined in this post. So wasteful

  3. #3 Greg Laden
    March 19, 2008

    sed command accomplished

  4. #4 blf
    March 19, 2008

    So ‘blfnig’ could be a good name for a shell script you may right. [sic] Except it isn’t because it does not convey any meaning.

    Now hang on a second here! I think that’s a rather good name. Or at least the first three letters of it… ;-)

    Slightly more seriously, I have a small tendency to name my commands (scripts or otherwise) as words which are also acronyms. One favourite from many years ago was “dung”, which stood for “Distributed Unix Network Grapher”. That program found candidate paths through a unidirectional network that met various constraints on the input, intermediate steps, and output. The name was more meaningful than it looks, since, for its intended usage, some of the nodes and links in the graph represented machines and connections in a network.

    In the case of “blfnig”, the first thing that comes to mind is “blf’s sNarky Interwoo Generator”, which sounds like it might be a “eliza”(?)-type thingie to generate snarky comments for woo-woo blogs, presumably written or inspired by(? because of?) yours truly… ;-)

  5. #5 Greg Laden
    March 19, 2008

    Cool idea. … working on it now..

  6. #6 Rick Pikul
    March 19, 2008

    A better way to check if a name is in use is to use the “which” command.

    This way, you don’t accidentally run a command that will do something you don’t like. Also, it will give you some idea of the importance of the command based on where it is.

  7. #7 Greg Laden
    March 19, 2008

    Rick:

    THANK YOU!!! I knew that but totally blanked on it and was going nuts trying to remember/find/look that up.

    Everybody: Do what Rich said.

  8. #8 386sx
    March 19, 2008

    If there are multiple commands on your system with the same name, there is a certain order in which the shell searches for the command.

    “hash” is another cool one. It can, for example, make bash know where a comand is and it doesn’t have to be in $PATH.

    hash -p ~/stuff/other_vim vim

  9. #9 Trinifar
    March 19, 2008

    I have, at times, been particularly adroit with bash scripting, but these days I quickly tire of yet another language that I need to learn to get something done — or of having to remember some strange syntax. Bash is especially arcane and that’s my problem with it. Fine 30 years ago, but not good today.

    Cshell is another option, and tshell, and …. Your readers should note you can tell your Unix which shell language to use as a default (Python anyone?) even while being able to override the default at will.

    Thing is, most of us master a new language when we have the need to use it and to the extent of that need. If we don’t use it for some time, we lose the dexterity of working with it. That’s my experience anyway.

    Ruby, Python, tckl, BeanShell, javascript, … the list goes on endlessly and on the back of C, C++, COBOL, FORTRAN, Java, Forth, SmallTalk, Prolog, LISP in all its flavors, Eiffel, ….

    Those of us who adapt to and learn new languages quickly survive. The large majority of people get lost in the tower of Babel.

Current ye@r *