I 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.
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.
# 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
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
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*
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.
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….