Istanbul Bilgi University Department of Computer Science
Previous Home > Courses > Year 1 > Comp 151 > LectureNotes Week 09 Next
Home
   About This Site
   Academic Policies
   Academic Staff
   Acm-istanbul
   Courses
      Course Descriptions
      Year 0
      Year 1
         Cmn 147
         Comp 111
         Comp 112
         Comp 149
         Comp 150
         Comp 151
            Archive
            Comp151 Homeworks
            LectureNotes Week 08
            LectureNotes Week 09
            Sample02 (pdf)
            Example (pdf)
            Sample (pdf)
            Worksheets
         Comp 152
         Comp 197
         Comp 198
         Sci 161
         Voc 109
      Year 2
      Year 3
      Year 4
   Curiosity Corner
   High School Computer Clubs Project
   Lab Rules
   Links
   Member Help
   News
   Other Stuff
   Standards Project
   Tanitim
   Turing Days
   Usage Statistics
   Yarışma

=====================================
COMP 151 - Lecture Notes
=====================================


-------------------------------------------------------
PROGRAMS AND COMMANDS: How does Bash execute commands?
-------------------------------------------------------

A "program" is a file that is "executable", and preferably marked as executable. Almost every Linux command is such a program. The only exceptions are Bash built-in commands. You can see a list of builtin commands by using the builtin command "help":

  $ help

The commands listed at the output of "help" command are natively recognized by Bash. For any other command, Bash does the following:
    (1) Check the environment variable called PATH. This tells Bash in which directories it should look for programs. The "env" builtin command will tell you the value of PATH (along other environment variables). A typical PATH is as follows:
        PATH=/sbin:/bin:/usr/sbin:/usr/bin
    which contains four directories.
    (2) For each directory in PATH, Bash checks if that directory contains a file that has the same name with the command. If there is, and the user has the right to execute the file, it is executed. If user does not have the execute right, Bash tells you that "access is denied".
    (3) If none of the directories contain such a file, Bash tells you that "command not found".
    
You can interrogate where does Bash find the program, using "which" builtin command, as follows:

  $ which cat
  /bin/cat
The output reports that the program "cat" is found under /bin directory. On the other hand:
  $ which links
  /usr/bin/links

If you go and check the file, you will see that it is indeed executable:
  $ ls -l /bin/cat
  -rwxr-xr-x  1 root root 16504 Jul 16  2004 /bin/cat
Although the file is owned by root (the super administrator of any Linux system), every user has the right to execute it, thus execution is allowed.

How does Bash know how to execute a program. There are dozens of programming languages and Bash have no idea about any of them!

When Bash needs to run(execute) a program (i.e. a file that is executable), it first checks the type of the file. We can do this ourselves using the "file" command:
  $ file /bin/cat
  /bin/cat: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0, dynamically linked (uses shared libs), stripped

This is cryptic! But briefly it tells us that the file is directly "executable" on the Intel CPU. This is a binary file which is written in the language that the hardware (CPU) can directly understand. In fact if you try to look at the file, Bash will warn you as follows:
  $ less /bin/cat
  "/bin/cat" may be a binary file.  See it anyway?

There is a second group of programs. An example is "base-config", which is used to configure a Debian GNU/Linux system at the beginning:
  $ which base-config
  /usr/sbin/base-config
  $file /usr/sbin/base-config
/usr/sbin/base-config: Bourne shell script text executable

This is different from /bin/cat. It is also executable, but not directly by the hardware. It is written in Bash language. So in fact it is a readable text file. Let's see a few lines from the file using "head" command, which shows first 10 lines of a file:
  $ head /usr/sbin/base-config
        #!/bin/sh
        # This program handles debian's second stage install -- after installing
        # the base system and rebooting, the inittab runs this program.
        set -e

        DI_DB=/var/log/debian-installer/cdebconf/questions.dat
        LIBDIR=/usr/lib/base-config
        MENUDIR=$LIBDIR/menu

        TEXTDOMAIN=base-config

All Bash cares here is the first line which contains "#!/bin/sh". The "#!" in the first line of an executable file is called "the interpreter line". It is a special sign for Bash and it tells Bash the name of a program that knows how to interpret(run) the commands in this file. In our example it is the program "/bin/sh". Bash will run this program and give the name of base-config to it as a parameter. So in fact, running "base-config" command is same as running "/bin/sh /usr/sbin/base-config". But this convenience helps us, the users, not to worry about typing long commands and needing to know all that.

However we can use this ability to create our own little programs without actually knowing how to program!

NOTE: /bin/sh is indeed a link to bash. This is a common convenience in GNU/Linux systems for which many alternative shells (like Ash, Corn shell, Z Shell, etc.) are available. /bin/sh is always a link to default system shell.

------------------------------------
GROUPING COMMANDS INTO BASH PROGRAM:
------------------------------------
Let's first create a directory to put our own programs. "programs" directory under our home would be a convenient place for this:
    $ cd                # to go to our home firectory
    $ mkdir programs    # to create the directory
As the next step let's create the program file, say "myfirstprog", using some text editor, such as "pico"
    $ pico programs/myfirstprog
Now let's put the following line into our file:

    echo "Hello. I am a Bash program"
    echo "but a very simple one"

At this point our file contains a single Bash command. The "echo" command is simply for writing (echoing) a text to the screen. Note that this file is not yet a program, for several reasons: (1)we have not marked it as executable, (2) we did not put and "interpreter line" so that Bash will know how to run the program, and (3) it is not in the PATH. 

However we can run our program by explicitly calling the interpreter as follows:
    $ bash programs/myfirstprog
    Hello. I am a Bash program
    but a very simple one
This is inconvenient if we want someone else to use our program since they will need to know which interpreter to use, or if we ourselves need to type this long command every time to run it. 

So let's turn it into a real program by doing the following:
    $ chmod +x programs/myfirstprog
now we can run the program by directly calling it:
    $ programs/myfirstprog
    Hello. I am a Bash program
    but a very simple one

Note that Bash did not need an interpreter line! Since our program contains Bash commands, it works without an interpreter line. Bash simply assumes that any executable file that is not a binary (such as /bin/cat above) is one that contains Bash commands. 

Thus we can skip worrying about the interpreter line for Bash programs. However if we want to be able to run the program by simply calling its name ("myfirstprog"), we have to change the PATH, as follows:

    $ PATH=$PATH:~/programs

We have to stop for a moment to understand this weird looking command, because it uses something called "variable" in the Bash environment. What we did above is to set the value of PATH variable to something new. The equal sign, "=", is used for this assignment:
        variable=new-value-for-variable
So in fact, we could use a command as follows to set the PATH to a new value so that it will include the "programs" directory under our home (remember that the tilde, "~", is a shortcut for our home:
    $ PATH=/bin:/sbin:/usr/bin:/usr/sbin:~/programs
The command above would give us what we want, but it is possible that our system had some other directories included in the PATH. What we wanted was to add ~/programs to PATH. The first command does exactly that: it takes the current value of PATH ( the $PATH) and appends ~/programs to it by using the column, ":", as seperator. When Bash sees something prefixed by a dollar sign, "$", it will expand it to its value. For example, the following command will print the value of PATH:
    $ echo "The Path is --> $PATH"

After setting the PATH appropriately, we can now call our program by directly mentioning its name:
    $ myfirstprog
    Hello. I am a Bash program
    but a very simple one

---------
EXERCISE:
---------
    Write a program that uses an interpreter line so that it will count the words in itself! You can use the wordcount program, "wc", as interpreter.
    
    SOLUTION:

    #!/usr/bin/wc
    Please count me!
    
------------------------------------
PASSING PARAMETERS TO BASH PROGRAMS:
------------------------------------
Bash is a very rich language which offers a variety of expansions in addition to the variable expansion we have mentioned above. But for the purposes of this course, we are only interested in passing simple parameters to our Bash programs so that we can have basic control on how they work.

When Bash executes a program, the parameters given on the command line are made available to the program with names 0,1,2,..., etc. Variable number zero is the name of the program itselfi and variables 1,2,... are the actual parameters that come after the name of program.

As an example, let's create a second program called "mysecondprog", in programs directory and put the following commands into it:
    #!/bin/sh
    echo "Hello. I am a Bash program"
    echo "  my name is: $0 "
    echo "  my first parameter is : $1 "
    echo "  my second parameter is: $2 "

(We have said that first line, the "interpreter line", is unnecessary for Bash programs, but it is a good habit to put it anyway!)

Let us turn this file into a program as we did before by making it executable:
    $ chmod +x ~/programs/mysecondprog
Now let's run it as follows (I assume that you have set the PATH variable accordingly):
    $ mysecondprog
    Hello. I am a Bash program
      my name is: mysecondprog 
      my first parameter is : 
      my second parameter is: 
    
Since there were no command line parameters, the values of $1 and $2 are empty. Let's try to run our program with some parameters:
    $ mysecondprog abc 123 xyz
    Hello. I am a Bash program
      my name is: mysecondprog 
      my first parameter is : abc
      my second parameter is: 123

Our little progam is "programmed" to use only the first and second parameters, so the third one does not show up. There is a way to know the number of parameters but it is beyond the scope of our course here.

In addition to command line parameters, a program can read additional values from the user using "read" command, as in the following example:
    #!/bin/sh
    echo "Please enter a filename to wordcount:"
    read x
    wc $x

---------
EXERCISES:
---------
    (1) Write a bash program which takes a URL as its first parameter, dumps its text only version using "links -dump" and counts the lines, words ,letters in it using wc.
    
    SOLUTION:
    #!/bin/bash
    echo "Please wait while I am downloading $1"
    links $1 | wc
    echo "bye"