Basics for running your own scripts

Slashdot it! Delicious Share on Facebook Tweet! Digg!
Computec Media GmbH

Computec Media GmbH

Dot Before Slash

Many Linux beginners stumble over the fact that you need to precede any calls to your own scripts or programs with a ./ combination. What's up with these dot-slashes?

The ./ character duo – a dot-slash – should be familiar to most experienced Linux users as a command prefix. However, Linux beginners may have a tough time getting used to it when running a program or script from the current shell directory. What's behind this cryptic practice, and why is it always necessary? I will shed a little light on the topic in this article.

Before I dive into the matter, I'll step back and talk a little about the Linux shell and the $PATH environment variable. A shell is essentially a simple program providing a text interface for entering commands that the shell ultimately executes. Apart from the widespread Bash Bourne shell, there are other, simpler ones such as the Zsh shell. However, I will be focusing on the Bash shell exclusively.

When calling a command, the shell executes either a built-in one or starts an executable program or script that's located somewhere on your hard drive. The first group includes command such as cd , echo , kill , or alias . These are part of the shell itself and don't require an independent program file. In contrast, executable programs such as mv and less or larger applications such as gedit or firefox are mostly included as program files in the /usr/bin/ directory.

When you enter a shell command, the shell first searches in the location set by the $PATH environmental variable for the executable program (Listing 1). The sequence of directories determined therein is what matters. If the shell is looking for the foo file and finds it in the /usr/local/bin directory set shown in Listing 1, it executes the program as /usr/local/bin/foo – even if /usr/bin/ also contained a foo file. The shell parses the paths in order and uses the first one listed – an important thing to keep in mind.

Listing 1

Shell Search

$ echo $PATH
/usr/local/sbin:/usr/local/bin:\
  /usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Executing Scripts

Now I'll return to ./ and talk somewhat about executing programs and scripts. Suppose you want to call a self-written script or a downloaded binary program. You call the script sample.sh and put it in the tmp/ directory of your home directory. Without much fuss, you can use cd to move to the directory, make the script executable, and use ls to see that the executable bit is truly set. You call up the script, and, voilà, nothing happens. The shell returns a command not found error (Listing 2).

Listing 2

Command Not Found

tux@computer:~$ cd tmp
tux@computer:~/tmp$ chmod +x sample.sh
tux@computer:~/tmp$ ls -al sample.sh
-rwxr-xr-x 1 tux tux 61 2010-02-03 15:28 sample.sh
tux@computer:~/tmp$ cat /sample.sh
#!/bin/bash
echo "This is only a sample script."
tux@computer:~/tmp$ sample.sh
sample.sh: command not found

But, the script is in the right location and has the proper file privileges. Why doesn't the shell want to run it? The answer is in the previously described $PATH variable. Take another look at it in Listing 1.

The shell discovers that nowhere in the list of directories set in the $PATH variable is there an example.sh file. Searching its own internal commands fails as well. The shell really should look into the current directory, but it doesn't. Instead, it suspends the program search immediately after checking the paths and its internal commands.

Therefore, the sample.sh script should really be in one of the directories set in $PATH or else you need to prefix the call with the full path to the file. Listing 3 provides three path options you could use.

Listing 3

Path Options

tux@computer:~/tmp$ /home/tux/tmp/sample.sh
This is only a sample script.
tux@computer:~/tmp$ $HOME/tmp/sample.sh
This is only a sample script.
tux@computer:~/tmp$ ~/tmp/sample.sh
This is only a sample script.

As you can see, there are a few ways to handle it, such as by preceding the path with a tilde (~ ), which is shorthand for the user's home directory. The shortest way to describe the current directory is with a simple dot (two dots go to the parent directory, something you will already be familiar with from using the cd .. command). Therefore, moving to the example.sh file's location and using a dot-slash (./ ) before its name is enough to run it (Listing 4).

Listing 4

Using ./

tux@computer:~$ cd tmp
tux@computer:~/tmp$ ./sample.sh
This is only a sample script.

Security Before Convenience

The question might be, why isn't the current directory in the path? It works that way at the Microsoft prompt. It would save a lot of typing and confusion especially for Linux beginners. The reason is simple: It's all about security.

Suppose someone gives you a USB stick containing a whole lot of useful files you wish to copy using shell commands. That's not hard. You simply use cd to move to the directory on the USB stick and use mv to move the files to your hard drive (Listing 5).

Listing 5

Using mv

tux@computer:~$ cd /media/usb-stick
tux@computer:/media/usb-stick$ mv sample.* /where/ever/desired

What if the USB stick also had a mv file with the content in Listing 6? If the shell didn't ignore the current directory, the malicious code in mv would take effect instead of the desired /usr/bin/mv command. Instead of saving the files to the hard drive, your entire home directory would disappear without your even knowing it – until it's too late.

Listing 6

Malicious mv

#!/bin/bash
echo "mv me and I'll delete you!"
rm -rf $HOME

Buy this article as PDF

Express-Checkout as PDF

Pages: 2

Price $0.99
(incl. VAT)

Buy Ubuntu User

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content