Making Your Programs Executable
Introduction
My linguistics work involves many things, one of which is the maintenance and creation of dictionaries. While there are many tools at my disposal, I often find myself writing shell scripts or short Perl programs to facilitate the tasks.
One inconvenience of scripting is that my script have all needed to be local to the directory in which they would run. During my last project, I finally decided to learn how to make my scripts executable.
In principle this is not difficult on Unix based systems. In fact it takes a single shell command to make a program executable. In practice, as I found out, there are a few other things that you need to do as well.
Working Undercover
In order to take advantage of of this procedure you will have to get familiar with Mac's Terminal program. If you have worked with Perl or Shell scripting then you should already know about Terminal. If your just getting started with scripting, then by all means pick up a book or locate a tutorial online. Maybe at some point, I will do a more basic introduction, but for now I will assume that you are familiar with the Terminal and the shell which runs within it.
Location, location, location!
Most everyone is familiar with the Applications Folder. That is the directory where all of your applications are stored. What many people are unaware of is that there are at least 4 other locations where programs are located on your computer. These are located in hidden directories on your computer. The point is that your operating system and more specifically the Unix under OSX has specific places where system-wide utilities and commands are stored.
Following their example, we should have a place to store our own executable programs. This will prevent us from accidently "breaking" anything. The typical location for such a directory is in your local users directory. Open the Terminal program (Applications/Utilities/Terminal) and at the prompt type pwd. If you see something like this:
Example 1.
If the pwd (present working directory) doesn't say /Users/YourUserName, then type cd ~/ and press enter. This will change directory to your home directory. You can also type in cd /Users/YourUserName and accomplish the same thing.
Of course you can also use finder for this part as well. In the left view panel select your home directory.
Example 2.
You can see that I have create a new folder titled PerlTools. Choose a folder name carefully if you wish to avoid repeating the next step. This is where we will put our executable scripts and other programs/tools we have created.
Finding Your Way Home
Once you have created your new personal program directory you must tell the operating system how to find it. This is accomplished by establishing a path to the new directory.
The default path for my bash shell is PATH="/bin:/sbin:/usr/bin:/usr/sbin". This translates to saying that when I type a program name that the shell should look in the /bin, /sbin, /user/bin, and /user/sbin directories for the program and execute it. By the way the first "/" (called a slash) is shorthand for the root directory on your main hard drive. In Example 2. above that is the PBook HD directory. So /bin means the bin director in the root directory on your harddrive.
We could have created out new executable programs directory in the root directory instead of the local /Users/YourUserName directory. The difference would be (mainly applicable to multi-user systems) that in the root directory everyone on the systems has access to your executable files. By locating them in the /Users directory we are making them available only to the owner of that directory.
Assuming we'll continue with our original plan of using the /Users/YourUserName directory, we must now tell the shell how to find that directory when looking for programs.
The PATH Variable
The PATH variable is contained in one of several start up file(s) required by your operating system. If you are using a bash shell (the default on newer Macs) this file is the /etc/profile located in your root directory. To see this file type the following command: cat /etc/profile and press enter/return. You should see something similar to Example 3.
Example 3.
This is the system wide profile for your system. The PATH variable is
"PATH="/bin:/sbin:/usr/bin:/usr/sbin"
Our goal is to append this path with "~/OurNewExecutableFolder" for our local user directory. (I do not recommended that you modify the /etc/profile itself.) To do this we need to identify or create a local users profile on our system.
First verify that you are in your local users directory by type "pwd". It should look similar to Example 1. above. If don't see "/Users/YourUserName" then type "cd ~/" to move to this directory.
Now type "ls -a" and press enter. This command will list the current directory and the -a option tells the command to reveal all of the hidden files. We want to locate one of three possible hidden files:
~/.bash_profile
~/.bash_login
~/.profile
These files give your bash shell additional/changed information beyond what is specified in the /etc/profile. These files when found are read in the order presented above. When the first file is located and read, the process stops. That means if you have a ~/.bash_profile and you have added information to a ~/.profile, your ~/.profile information will not be found.
Open the appropriate file using a text editor or if you need to create a file, create the .bash_profile. To do this open your text editor and enter the following line:
export PATH="$PATH:/YourNewExecutableDirectoryName"
For example my .bash_profile contains this line:
export PATH="$PATH:/PerlTools"
This command tells the system that wish to append to the current path (see above) the new path. If you were to look at the new path you would see this:
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/Users/genedeal/PerlTools
Now you are ready to create your first executable Perl or Shell script.
Creating the Executable Script
Create an actual executable script at this point is quite easy. First you need a script. Open your text editor again and type in the following two lines:
#!/bin/sh
echo "Hello World"
Save this file in your new executables folder:
/Users/YourUserName/YourNewExecutableFolderName as "hello.sh"
Now from the Terminal program prompt type chmod 755 hello.sh and press enter.
Next change to another directory such as /Users/YourUserName/Public/Drop Box. Type ls or ls -a at the shell prompt and verify the your new script "hello.sh" is not located here.
Now type "hello.sh" (without the quotes) and you should see something like this:
Example 3.
One note of caution here. These .sh shell scripts and .pl Perl files must be saved (on the Mac/Unix platform) using Unix linefeeds. If you are using an editor allowing options for the linefeed types, watch this. It will result in unpredictable responses from the script or if your lucky, it simply will not run. Anytime I have a problem with a simple script, I always check the line feed defaults first. (This is a problem because I work on both Mac and PC platforms, so out of consideration for my PC friends I have my default linefeeds set to a PC/DOS configuration.
Summary
So if all went well, you have achieved the following:
created a Folder/Directory for your executable scripts
created a .bash_profile to append the executable path to your new directory
created a short "hello.sh" shell script
change the attributes of the "hello.sh" file to create an executable file
executed the executable from a non-local directory with success...
All of this just to say "hello world"!
You have also managed to cover the principle necessary to apply this to more complicated scripts making them available from within any of your working directories. No more hunting and copying scripts to get you job done.