Bash Scripting for Ubuntu: Episode 3

Welcome to Episode 3

This episode is mostly about variables, which are names for places in memory where you will store values. Values can be strings of characters or numbers. Bash doesn’t require you to choose which type of value you are going to use to fill your variable.

Variables in Bash Scripting

The script below shows how to assign and use a simple variable. In general, shell variables are all treated as strings. A string is a series of characters, the content of which are ignored by the shell. Shell programming required you to get the syntax right. In the assignment there must be no space between the variable name and the equals sign, or the equals sign and the value. To use the variable, it is prefixed by a dollar ‘$‘ character.

#!/bin/sh
# name is a variable
name="Ferdinand" # This is an assignment of a value to a variable
                 #  called “name.”
echo "The name is $name"  # This line is calling the variable
                          #  called name.

The script above would generate a line that read, “The name is Ferdinand”

The special variables $1-$9 correspond to the arguments passed to the script when it is invoked. For example, if we rewrite the script above as shown below, calling the script Yourname.sh, and then invoke the command Yourname.sh Ferdinand Quacker, the message “Your name is Ferdinand Quacker” will be printed out:

#!/bin/sh
# Yourname.sh
echo "Your name is $1 $2"

wolf@Lab5-ubustudio:~$ sudo chmod +x Yourname.sh 
[sudo] password for wolf: 
wolf@Lab5-ubustudio:~$ ./Yourname.sh      
Your name is  
wolf@Lab5-ubustudio:~$ ./Yourname.sh Ferdinand Quacker 
Your name is Ferdinand Quacker 

Where I “forgot” to define the variables $1 and $2, the script ran great but produced no visible output.

Naming Conventions in Bash Scripting

You can choose almost any name for your variables, and textbooks often use one-letter variable names such as “A,” “B” and “C.” This makes a short example for the textbook, and in certain situations is the best kind of name for a variable. Some requirements of bash variable names are that they cannot contain spaces and they cannot start with a digit. Many sources for bash scripting help suggest you always use upper-case letters in a variable name, like “WEIGHT,” or that you always use lower-case letters, like “weight.” It is most important to keep some regularity in your variable-naming.

The most common conventions are

Single word: Where the name of the variable is a single word that is descriptive of what the content of the variable will be. “height,” “weight,” “colour,” “description” or understandable shortenings of the words like “desc,” “mnths,” “hght,” and so on. Keep in mind that the name of a variable can help future readers of your code to understand what you meant the script to do. That future reader might be you!

Underscore_Separated words: Where the variable name is two or more words separated by an underscore. Underscore is the name for the character that results from holding the shift key down and tapping the hyphen or dash. “_” between words is treated by the shell program as if there is no space between the words but is readable as if there is a space, e.g., “points_scored,” “monthly_expenses,” “sum_of_entries” This convention makes the code easier to read.

CamelCase or StudlyCapitals: CamelCase uses two or more words to name a variable, but instead of an underscore, camelCasing capitalizes the first letter of the internal words.

Arithmetic in Bash Scripting

Shell scripts can also do math but it is not a great way to spend your (computer’s) time. The script below will produce a Fibonacci sequence. A Fibonacci sequence takes one number and adds the next number to it to produce the third in the sequence and then takes #’s 2 and 3 to make #4 in the sequence and so on. In a Fibonacci sequence, denoted by F0 , F1 , F2 , F3 , F4 , … [where the subscribed numbers ( 0, 1, 2, 3, 4 , … ) are indices identifying the consecutive members of the sequence], any member is the sum of its two immediate predecessors. Thus, beginning with F0 = 0 and F1 = 1 , for j = 2, 3, 4 , 5, … , every Fj = Fj-1 + Fj-2 .” If you set the MAX constant to 40, you will notice that it takes more than twice as much time as calculating 20 entries in the Fibonacci series. Simple formulae work quickly enough, but long and complicated formulae may work better in in compiled programs. There are ways to have Bash scripts call compiled program modules, so there is no problem if you really must have a complicated problem to solve.

#!/bin/bash 
# fibonacci.sh : Fibonacci sequence 

MAX=20     # a constant, denoting Number of terms (+1) to generate. 
MIN=2      # another constant. 
           #If index is less than 2, then Fibo(index) = index. 

Fibonacci () 
{ 
  fsn=$1   
  if [ "$fsn" -lt "$MIN" ] 
  then 
    echo "$fsn"  # First two terms are 0 1 ... see above. 
  else 
    (( --fsn ))  # j-1 
    term1=$( Fibonacci $fsn )   #  Fibo(j-1) 

    (( --fsn ))  # j-2 
    term2=$( Fibonacci $fsn )   #  Fibo(j-2) 

    echo $(( term1 + term2 )) 
  fi 
}

for i in $(seq 0 $MAX) 
do  # Calculate $MAX+1 terms. 
  FIBO=$(Fibonacci $i) 
  echo -n "$FIBO " 
done 
# expected output:
#  0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

echo  " "
exit 0

If you copy the script into a file and run it, the first few numbers are found quite rapidly, but you could produce the last 10 places in the sequence on paper or (possibly) in your head without a calculator before the shell script could find them.

Shell Variables

Like every other programming language, shells support variables. Shell variables may be assigned values, manipulated, and used. Some variables are automatically assigned for use by the shell. Some variables are environmental variables. These variables can effect how programs run outside of the shell, and you might want to be careful naming your shell variables the same as any of these. The following is a list of the environmental variables on Lab5-ubustudio. Note: I am calling the env list from a different directory, and it is all in my command prompt. Your machine might only show you only the last directory in the path. You can customize this by changing the Environmental Variable that holds the prompt information. That Variable is PS1 at the top of the abbreviated list below. You may notice that the Environmental Variables below are all centered around a specific user If somebody else were to log in to this machine, a lot of the Environmental Variables would be changed. Another way to look at how your system is set up is to type set at the command line. That will show you even more Environmental Variables.

wolf@Lab5-ubustudio:~/Documents/Projects/basho$ env

PS1=’\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ‘

ORBIT_SOCKETDIR=/tmp/orbit-wolf

TERM=xterm

SHELL=/bin/bash

USER=wolf

USERNAME=wolf

XDG_CONFIG_DIRS=/usr/share/ubuntustudio-menu/:/etc/xdg/

DESKTOP_SESSION=gnome

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

PWD=/home/wolf/Documents/Projects/basho

GDM_KEYBOARD_LAYOUT=us

LANG=en_US.UTF-8

GDM_LANG=en_US.UTF-8

GDMSESSION=gnome

SHLVL=1

HOME=/home/wolf

LOGNAME=wolf

COLORTERM=gnome-terminal

This is the end of episode 3.  Please stay tuned for another riveting episode soon.

== Wolf Halton is CEO of Atlanta Cloud Technology, Inc. ,  a guest writer on security topics here, at  and owner of Wolfhalton.info.

Posted in Bash, Shell Script, Ubuntu Desktop | Leave a comment

Bash Scripting for Ubuntu: Episode 2

This is episode 2 of a serialized article

It was started to explain certain features of the bash shell scripting language. I will be posting it across several weeks as time permits.  please feel free to ask questions and we can answer them.  When the entire article has been serialized, I will send it for free to people who have offered comments.

The topic today is Comments – Who writes them and who needs them.  In this case the comments are not blog comments, which all blog writers prize but comments in the code, which are prized by the programmer who must follow up and add to or edit the code.

Comments are Your Friend

In the Bash shell, any line that begins with a pound ‘#‘ character in the first column is considered a comment and is ignored. The only exception is the first line in the file, where the comment is used to indicate which shell should be used (/bin/sh is the Bash shell). Use comments liberally to explain what a script is for, and what various lines are doing. You can even put a ‘#‘ sign in the middle of a line, but be careful. Everything in the line after the ‘#‘ is going to be ignored by the shell when reading your script.

All lines without a ‘#‘ character at the beginning are taken to be Linux or bash commands and are executed. Any Linux command can be used. For example, the script below displays the current directory name using the pwd command, and then lists the directory contents using the ls command.

#!/bin/sh
# look-around.sh
# print out current directory name and all contents
pwd
ls -al

The comments in this case are only at the top.  Line one is the previously-mentioned reference to where the shell program is in the file system of most Linuxes or Unixes (Unices?).  The second line is the name you have chosen for the file.  It is useful, especially if one is developing several scripts, to have that hint.  When editing a script in vi or nano, the name of the file being edited may not be visible, and this can cause issues, if one forgets which one is being edited.  The third line is a description of what the file does.  if this is your own script, you might not need this prompt, but it is helpful for those who follow you.

Inline commenting must be at the end of the line.  Everything after the # is ignored by the system.  The following line will fail to use grep to filter the results.

dmesg #(to look at hardware, piped to..) | grep nvidia #(to look for nVidia video cards)

If you have any comments about commenting, please comment below.

This is the end of episode 2.  Please stay tuned for another riveting episode where we answer the burning question, “What is an environmental variable, and where do I find them?”

== Wolf Halton is CEO of Atlanta Cloud Technology, Inc. ,  a guest writer on security topics here, at  and owner of Wolfhalton.info.

Posted in Bash, Shell Script | Leave a comment

Bash Scripting for Ubuntu: Episode 1

This is the start of a serialized article

It was started to explain certain features of the bash shell scripting language. I will be posting it across several weeks as time permits.  please feel free to ask questions and we can answer them.  When the entire article has been serialized, I will send it for free to people who have offered comments.

(Another) simple bash script

If you just type a series of commands into a file and make the file executable, the Linux bash shell will try to run the script as if it is a script written for a bash shell since that is the shell you are probably using if you are running Ubuntu, or many other Linuxes. Scripts for the c-shell or the z-shell might well fail under those conditions, so, to make sure the correct shell is invoked, the first line of the shell-script file should always tell the system what shell is to be invoked. Below is illustrated a simple Bash script: it just outputs the message “hello Linux User!”:

#!/bin/sh
# hello.sh this is the name of the file, and is just a reminder
# for you what you called it.
echo "hello Linux User!"
# This is a comment line, anything that follows a '#' sign
# is a comment.  Comments make a script more readable

Use a text editor, such as vi, nano (for the terminal), gedit or kate (for the GUI), to create a file with the lines above in it.  Personally, I recommend nano and kate in that order.   Save the file, calling it hello.sh. Then make the hello.sh file executable by typing:

$ sudo chmod 755 hello.sh

This uses the “octal permissions” feature of chmod. It makes the file executable for the owner (probably you, or root), the group and for everybody else.  You can then run the script by simply typing ./hello.sh This tells Linux that the file is a script, it is in the directory from which you are calling it, and runs the Linux commands inside it (in this case, just the echo command).  [Note: if you are hosting multiple users, you will have to put the files somewhere anybody can get at them, such as /usr/local/bin, in which case you would want to make sure they are owned by root.   Then anybody with a sign-in can run the file just by typing hello.sh ]

You can give your shell scripts almost any name you like. There are times when there might be another script built in to your distribution with the same name. Here is the content of the /bin directory of this Ubuntu 9.10 Linux box. Please note that your machine will put in the [name]@[computername]:[directory][access-level] sequence for your prompt as mine put in [wolf]@[Lab5-ubustudio]:[~][$]. If your access-level is shown as [#] then you are acting as root, or the administrative user for that sequence. If you are in the habit of starting sessions as root, this is a marvelous time to break that dangerous habit. In Ubuntu or Debian Linux distributions, you rarely see the root symbol as they use the sudo command to act as pseudo-root for just as long as you need to. Acting as root, when it isn’t required, should be avoided as a general rule.

wolf@Lab5-ubustudio:~$ ls /bin
bash dbus-daemon kill netstat tar
bunzip2 dbus-uuidgen less open tempfile
bzcat dd lessecho openvt touch
bzcmp df lessfile pidof TRUE
bzdiff dir lesskey ping ulockmgr_server
bzegrep dmesg lesspipe ping6 umount
bzexe dnsdomainname ln ps uname
bzfgrep dumpkeys loadkeys pwd uncompress
bzgrep echo login rbash unicode_start
bzip2 ed ls readlink vdir
bzip2recover egrep lsmod rm which
bzless FALSE mkdir rmdir zcat
bzmore fgconsole mknod run-parts zcmp
cat fgrep mktemp sed zdiff
chgrp fuser more setfont zegrep
chmod fusermount mount setupcon zfgrep
chown grep mountpoint sh zforce
chvt gunzip mt sh.distrib zgrep
cp gzexe mt-gnu sleep zless
cpio gzip mv stty zmore
dash hostname nc su
date ip nc.traditional sync
dbus-cleanup-sockets kbd_mode netcat tailf

If you just can’t avoid using one of these as a filename for your script, add the .sh and keep it in your home directory in a special file, or on your thumb-drive, and invoke your scripts from their own directory with the ./ sequence. You can check whether your name exists by using the which command. Which tells you where a specific command exists, if it does, and doesn’t tell you that it doesn’t exist, if it doesn’t. For instance to see if there are commands called open and sesame, type:

wolf@Lab5-ubustudio:~$ which open 
/bin/open 
wolf@Lab5-ubustudio:~$ which sesame 
wolf@Lab5-ubustudio:~$ 

Note the lack of response when you ask for something that doesn’t exist.

This is the end of episode 1.  Please stay tuned for another riveting episode soon.

== Wolf Halton is CEO of Atlanta Cloud Technology, Inc. ,  a guest writer on security topics here, at  and owner of Wolfhalton.info.

Posted in Bash, Shell Script, Ubuntu Desktop | 1 Comment