BASH Programming
BASH Programming
BASH Programming
Introduction
1.2 Requisites
Familiarity with GNU/Linux command lines, and familiarity with basic programming concepts is
helpful. While this is not a programming introduction, it explains (or at least tries) many basic
concepts.
This script has only two lines. The first indicates the system which program to use to run the file.
The second line is the only action performed by this script, which prints 'Hello World' on the
terminal.
If you get something like ./hello.sh: Command not found. Probably the first line '#!/bin/bash' is
wrong, issue whereis bash or see 'finding bash' to see how sould you write this line.
Here, a file called 'ls-l.txt' will be created and it will contain what you would see on the screen if
you type the command 'ls -l' and execute it.
Here, a file called 'grep-errors.txt' will be created and it will contain what you would see the stderr
portion of the output of the 'grep da *' command.
Here, the stderr portion of the command is sent to stdout, if you pipe to less, you'll see that lines that
normally 'dissapear' (as they are written to stderr) are being kept now (because they're on stdout).
This (thinking on the cron entry) will delete every file called 'core' in any directory. Notice that you
should be pretty sure of what a command is doing if you are going to wipe it's output.
4. Pipes
This section explains in a very simple and practical way how to use pipes, nd why you may want it.
4.1 What they are and why you'll want to use them
Pipes let you use (very simple, I insist) the output of a program as the input of another one
Here, the following happens: first the command ls -l is executed, and it's output, instead of being
printed, is sent (piped) to the sed program, which in turn, prints what it has to.
5. Variables
You can use variables as in any programming languages. There are no data types. A variable in bash
can contain a number, a character, a string of characters.
You have no need to declare a variable, just assigning a value to its reference will create it.
Line 2 creates a variable called STR and assigns the string "Hello World!" to it. Then the VALUE of
this variable is retrieved by putting the '$' in at the beginning. Please notice (try it!) that if you don't
use the '$' sign, the output of the program will be different, and probably not what you want it to be.
This script introduces another thing. First of all, you should be familiarized with the variable
creation and assignation on line 2. Notice the expression '$(date +%Y%m%d)'. If you run the script
you'll notice that it runs the command inside the parenthesis, capturing its output.
Notice that in this script, the output filename will be different every day, due to the format switch to
the date command(+%Y%m%d). You can change this by specifying a different format.
Some more examples:
echo ls
echo $(ls)
6. Conditionals
Conditionals let you decide whether to perform an action or not, this decision is taken by evaluating
an expression.
The code to be executed if the expression within braces is true can be found after the 'then' word
and before 'fi' which indicates the end of the conditionally executed code.
On the second line, we declare i to be the variable that will take the different values contained in $
( ls ).
The third line could be longer if needed, or there could be more lines before the done (4).
'done' (4) indicates that the code that used the value of $i has finished and $i can take a new value.
This script has very little sense, but a more useful way to use the for loop would be to use it to
match only certain files on the previous example
This script 'emulates' the well known (C, Pascal, perl, etc) 'for' structure
8. Functions
As in almost any programming language, you can use functions to group pieces of code in a more
logical way or practice the divine art of recursion.
Declaring a function is just a matter of writing function my_func { my_code }.
Calling a function is just like calling another program, you just write its name.
Lines 2-4 contain the 'quit' function. Lines 5-7 contain the 'hello' function If you are not absolutely
sure about what this script does, please try it!.
Notice that a functions don't need to be declared in any specific order.
When running the script you'll notice that first: the function 'hello' is called, second the 'quit'
function, and the program never reaches line 10.
This script is almost identically to the previous one. The main difference is the funcion 'e'. This
function, prints the first argument it receives. Arguments, within funtions, are treated in the same
manner as arguments given to the script.
9. User interfaces
If you run this script you'll see that it is a programmer's dream for text based menus. You'll probably
notice that it's very similar to the 'for' construction, only rather than looping for each 'word' in
$OPTIONS, it prompts the user.
What this script does should be clear to you. The expression in the first conditional tests if the
program has received an argument ($1) and quits if it didn't, showing the user a little usage
message. The rest of the script should be clear at this point.
10. Misc
As a variant, you can get multiple values with read, this example may clarify this.
#!/bin/bash
echo Please, enter your firstname and lastname
read FN LN
echo "Hi! $LN, $FN !"
11. Tables
I quote here a note from a mail, sent buy Andreas Beck, refering to use if [ $1 = $2 ].
This is not quite a good idea, as if either $S1 or $S2 is empty, you will get a parse error. x$1=x$2 or
"$1"="$2" is better.
11.3 Arithmetic operators
+
-
*
/
% (remainder)
Sed replaces the string 'to_be_replaced' with the string 'replaced' and reads from the /tmp/dummy
file. The result will be sent to stdout (normally the console) but you can also add '> capture' to the
end of the line above so that sed sends the output to the file 'capture'.
$sed 12, 18d /tmp/dummy
Sed shows all lines except lines 12 to 18. The original file is not altered by this command.
awk (manipulation of datafiles, text retrieval and processing)
Many implementations of the AWK programming language exist (most known interpreters are
GNU's gawk and 'new awk' mawk.) The principle is simple: AWK scans for a pattern, and for every
matching pattern a action will be performed.
Again, I've created a dummy file containing the following lines:
"test123
test
tteesstt"
$awk '/test/ {print}' /tmp/dummy
test123
test
The pattern AWK looks for is 'test' and the action it performs when it found a line in the file
/tmp/dummy with the string 'test' is 'print'.
$awk '/test/ {i=i+1} END {print i}' /tmp/dummy
3
When you're searching for many patterns, you should replace the text between the quotes with '-f
file.awk' so you can put all patterns and actions in 'file.awk'.
grep (print lines matching a search pattern)
We've already seen quite a few grep commands in the previous chapters, that display the lines
matching a pattern. But grep can do more.
$grep "look for this" /var/log/messages -c
12
The string "look for this" has been found 12 times in the file /var/log/messages.
[ok, this example was a fake, the /var/log/messages was tweaked :-)]
wc (counts lines, words and bytes)
In the following example, we see that the output is not what we expected. The dummy file, as used
in this example, contains the following text: "bash introduction howto test file"
$wc --words --lines --bytes /tmp/dummy
2 5 34 /tmp/dummy
Wc doesn't care about the parameter order. Wc always prints them in a standard order, which is, as
you can see: .
sort (sort lines of text files)
This time the dummy file contains the following text:
"b
c
a"
$sort /tmp/dummy
1 == 5
0
0.05 == 0.05
1
5 != 5
0
2^8
256
sqrt(9)
3
while (i != 9) {
i = i + 1;
print i
}
123456789
quit
tput (initialize a terminal or query terminfo database)
A little demonstration of tput's capabilities:
$tput cup 10 4
Clears screen and prompt appears at (y1,x1). Note that (y0,x0) is the upper left corner.
$tput cols
80
Shows the number of characters possible in x direction.
It it higly recommended to be familiarized with these programs (at least). There are tons of little
programs that will let you do real magic on the command line.
[some samples are taken from man pages or FAQs]
#we now get rid of the mode ($1) variable and prefix ($2)
prefix=$2 ; shift ; shift
# a quick check to see if any files were given
# if none then its better not to do anything than rename
some non-existent
# files!!
if [$1 = ]; then
echo "no files given"
exit 0
fi
if [$1 = ]; then
echo "no files given"
exit 0
fi
for file in $*
do
mv ${file} $file$suffix
done
exit 0
fi
shift
if [ $# -lt 3 ] ; then
echo "usage: renna r [expression] [replacement]
files... "
exit 0
fi
for file in $*
do
new=`echo ${file} | sed s/${OLD}/${NEW}/g`
mv ${file} $new
done
exit 0
fi
# done!
criteria=$1
re_match=$2
replace=$3
for i in $( ls *$criteria* );
do
src=$i
tgt=$(echo $i | sed -e "s/$re_match/$replace/")
mv $src $tgt
done
14.2 Translations
Italian: by William Ghelfi (wizzy at tiscalinet.it) is here
French: by Laurent Martelli is missed
Korean: Minseok Park http://kldp.org
Korean: Chun Hye Jin unknown
Spanish: unknow http://www.insflug.org
I guess there are more translations, but I don't have any info of them, if you have it, please, mail it
to me so I update this section.
14.3 Thanks to
• People who translated this document to other languages (previous section).
• Nathan Hurst for sending a lot of corrections.
• Jon Abbott for sending comments about evaluating arithmetic expressions.
• Felix Hudson for writing the renna script
• Kees van den Broek (for sending many corrections, re-writting usefull comands section)
• Mike (pink) made some suggestions about locating bash and testing files
• Fiesh make a nice suggestion for the loops section.
• Lion suggested to mention a common error (./hello.sh: Command not found.)
• Andreas Beck made several corrections and coments.
14.4 History
New translations included and minor correcitons.
Added the section usefull commands re-writen by Kess.
More corrections and suggestions incorporated.
Samples added on string comparison.
v0.8 droped the versioning, I guess the date is enought.
v0.7 More corrections and some old TO-DO sections written.
v0.6 Minor corrections.
v0.5 Added the redirection section.
v0.4 disapperd from its location due to my ex-boss and thid doc found it's new place at the proper
url: www.linuxdoc.org.
prior: I don't rememeber and I didn't use rcs nor cvs :(