Pound Bang Slash Bin Slash Bash – A Script To Write Scripts

I thought I’d share some of my linux geekiness today and share one of the scripts I keep in my personal arsenal. This is one I’ve had for some time that I use quite often. It is very simple and it does one thing very quickly. It creates a script. What? Yep. Every get tired of typing #!/bin/bash and all the stuff that follows? Well keep reading.

Let’s just dig right into the script itself and see what it does. The first part of the file sets up some default values as you can see here. Nothing complicated; an author, company and file mode. If you do not know what that file mode means then you are probably in the wrong blog post. 😉 All hope is not lost though; why not check out A Practical Guide to Linux(R) Commands, Editors, and Shell Programming. Or if you can’t wait for shipping you can check out the Linux For Dummies website. It’s in a forum style and breaks down a lot of the basics in human readable language.

DEFAULT_AUTHOR="Jonathan Franzone"
DEFAULT_COMPANY="Franzone Technology Solutions"
DEFAULT_MODE=700

Next I create a user defined function that simply appends the given argument to a file. This is just to ease the pain of having a bunch of echo >> $FILE_NAME statements in the rest of the script. Notice the function declaration doesn’t actually have any parameters? That may look pretty strange to any of you C/C++ programmers out there, but oddly enough it is correct. Inside the function you just refer to the command arguments via $1, $2, etc. but you have to make sure you check yourself that they are valid. The -z flag is the “is empty” flag so the first test I perform is: if the first command argument is NOT empty. Then it just appends whatever is in that argument out to $FILE_NAME which is a global variable (to the script) which it is referring to.

fwrite () {
if [ ! -z "$1" ]; then
echo "$1" >> $FILE_NAME
fi
}

Now we gather command line arguments and prompt the user for input as needed. Notice the same test for the empty first command argument? Only this time it is not inside a function so it is referring to the script’s first command argument. So if the user calls the script with a file name on the command line it assigns that to the $FILE_NAME variable and continues, otherwise it will prompt the user for the filename. The script continues this process for several other variables.

if [ ! -z "$1" ]; then
FILE_NAME=$1
fi
while [ -z "$FILE_NAME" ]
do
echo -n "File name : "
read FILE_NAME
done
# MORE Following ...

We are ready to start writing our file contents, but we don’t want to append to an already existing file. I could have included the ability to warn of existing files or backup existing files, but if I’m that dumb then I deserve it! I’ll leave that as an exercise for the reader. 🙂 Anyway, this just forces a delete of the given filename and then immediately creates a file with the given filename.

rm -f $FILE_NAME
touch $FILE_NAME

Write out the header to the file. First to note is the use of the basename command to remove any path information from the $FILE_NAME when writing it to the header. This will give us just the filename itself, which is what we want. The script outputs the date that the script was created. You can of course format this however you want to. The last line of this I’d like to point out. I used to set $PDIR (project directory) to `pwd` (print working directory). This was usually fine, but sometimes I wanted the project directory to be exactly as I had called the script. For instance if I had called the script as ./ScriptName then I would like for $PDIR to be ./. The last line accomplishes this nicely by setting $PDIR to the $0 command argument which is the calling script, but then it uses the % replacement variable magic to remove the substring `basename $0` from the back of the variable. You may not think it cool, but I like it.

fwrite "#!/bin/bash"
fwrite "# --------------------------------------------------"
fwrite "# File : `basename $FILE_NAME`"
fwrite "# Author : $AUTHOR"
fwrite "# Company : $COMPANY"
fwrite "# Date : `date +%m/%d/%Y`"
fwrite "# Description : "
fwrite "# --------------------------------------------------"
fwrite " "
fwrite "# --------------------------------------------------"
fwrite "# Setup Environment"
fwrite "# --------------------------------------------------"
fwrite "PDIR=\${0%\`basename \$0\`}"

You could throw in any number of extra things here at this point. If you wanted to you could put in a listing of ABBA’s Greatest HitsAbba’s Greatest Hits. It’s totally up to you.

Finally I change the file mode so that it is executable.

chmod $MODE $FILE_NAME

If you liked this sort of thing you can check out more in the Advanced Bash-Scripting Guide on The Linux Documentation Project. I keep it bookmarked at all times as it is an invaluable resource. Also if you would like to you may download the entire script that I use. I have changed the file extension to .txt to prevent any browser download weirdness. You should be able to just rename it without an extension on linux or you can use a .bash extension if you like. * NOTE This also runs on cygwin. 🙂

DOWNLOAD BashTemplate.txt [4kb]