diff --git a/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml b/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml new file mode 100644 index 00000000..627cc6a5 --- /dev/null +++ b/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml @@ -0,0 +1,696 @@ + + + + + + +
+ BASH Programming - Introduction HOW-TO + by Mike G + v0.04, 31 January 2000 + + This article intends to help you to start programming + basic-intermediate shell scripts. It does not intend to be an + advanced document (see the title). I am NOT an expert nor guru + shell programmer. I decided to write this because I'll learn a + lot and it might be useful to other people. + + + + + + + +Introduction + + Getting the latest version + +

Download latest version + + +

Get sgml source + + +

View it online + + + + + + 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. +

+ + + Uses of this document +

This document tries to be useful in the following situations + + You have an idea about programming and you want to start + coding some shell scripts. + You have a vague idea about shell programming and want + some sort of reference. + You want to see some shell scripts and some comments to + start writing your own + You are migrating from DOS/Windows (or already did) + and want to make "batch" processes. + You are a complete nerd and read every how-to available + + + + + + +Very simple Scripts + +

This HOW-TO will try to give you some hints about shell script + programming strongly based on examples. +

In this section you'll find some little scripts which + will hopefully help you to understand some techniques. + + + Traditional hello world script + + +

+ + #!/bin/bash + echo Hello World! + +

+

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. + + + A very simple backup script +

+ + #!/bin/bash + tar -cZf /var/my-backup.tgz /home/me/ + +

In this script, instead of printing a message on the terminal, + we create a tar-ball of a user's home directory. This is NOT intended + to be used, a more useful backup script is presented later in this + document. + + + + + +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. + + + + + Sample: Hello World! using variables +

+ + #!/bin/bash + STR="Hello World!" + echo $STR + + +

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. + + + Sample: A very simple backup script (little bit better) +

+ + #!/bin/bash + OF=/var/my-backup-$(date +%Y%m%d).tgz + tar -cZf $OF /home/me/ + +

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) + + + + + +Conditionals + +

Conditionals let you decide whether to perform an action + or not, this decision is taken by evaluating an expression. + + + + Dry Theory +

Conditionals have many forms. The most basic form is: + 1' + evaluates to true.xs +

Conditionals have other forms such as: + Yet another form of conditionals is: + A word about syntax: +

The base for the 'if' constructions in bash is this: +

if [expression]; +

then +

code if 'expression' is true. +

fi + + + + Sample: Basic conditional example if .. then +

+ + #!/bin/bash + if [ "foo" = "foo" ]; then + echo expression evaluated as true + fi + +

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. + + + Sample: Basic conditional example if .. then ... else +

+ + #!/bin/bash + if [ "foo" = "foo" ]; then + echo expression evaluated as true + else + echo expression evaluated as false + fi + + + + Sample: Conditionals with variables +

+ + #!/bin/bash + T1="foo" + T2="bar" + if [ $T1 = $T2 ]; then + echo expression evaluated as true + else + echo expression evaluated as false + fi + + + + + + +Loops for, while and until + + +

In this section you'll find for, while and until loops. +

The The The If you suspect that while and until are very similar you are right. + + + For sample +

+ + #!/bin/bash + for i in $( ls ); do + echo item: $i + done + +

+

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 +

+ + + + While sample +

+ #!/bin/bash + COUNTER=0 + while [ $COUNTER -lt 10 ]; do + echo The counter is $COUNTER + let COUNTER=COUNTER+1 + done + +

+

This script 'emulates' the well known + (C, Pascal, perl, python, etc) 'for' structure + + + + Until sample +

+ #!/bin/bash + COUNTER=20 + until [ $COUNTER -lt 10 ]; do + echo COUNTER $COUNTER + let COUNTER-=1 + done + + + + + + +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. +

+ + Functions sample +

+ 1) #!/bin/bash + 2) function quit { + 3) exit + 4) } + 5) function hello { + 6) echo Hello! + 7) } + 8) hello + 9) quit + 10) echo foo + +

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. + + + + + + +User interfaces + + + Using select to make simple menus +

+ + #!/bin/bash + OPTIONS="Hello Quit" + select opt in $OPTIONS; do + if [ $opt = "Quit" ]; then + echo done + exit + elif [ $opt = "Hello" ]; then + echo Hello World + else + clear + echo bad option + fi + done + +

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. +

+ + + + Using the command line +

+ + #!/bin/bash + if [ -z $1 ]; then + echo usage: $0 directory + exit + fi + SRCD=$1 + TGTD="/var/backups/" + OF=home-$(date +%Y%m%d).tgz + tar -cZf $TGTD$OF $SRCD + +

+

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. + + + + + + +Misc + + + Reading user input +

__TO-DO__ + + + + + Arithmetic evaluation +

On the command line (or a shell) try this: +

echo 1 + 1 +

If you expected to see '2' you'll be disappointed. What if + you want BASH to evaluate some numbers you have? The solution + is this: +

echo $((1+1)) +

This will produce a more 'logical' output. This is to evaluate an + arithmetic expression. You can achieve this also like this: +

echo $[1+1] +

+

If you need to use fractions, or more math or you just want it, you + can use bc to evaluate arithmetic expressions. +

if i ran "echo $[3/4]" at the command prompt, it would return 0 + because bash only uses integers when answering. If you ran + "echo 3/4|bc -l", it would properly return 0.75. + + + + + Capturing a commands output +

__TO-DO__ + + + + + Multiple source files +

__TO-DO__ + + + + + + +Tables + + + String comparison operators + +

(1) s1 = s2 +

(2) s1 != s2 +

(3) s1 < s2 +

(4) s1 > s2 +

(5) -n s1 +

(6) -z s1 +

+

(1) s1 matches s2 +

(2) s1 does not match s2 +

(3) __TO-DO__ +

(4) __TO-DO__ +

(5) s1 is not null (contains one or more characters) +

(6) s1 is null + + + + + Arithmetic operators +

+ +

- +

* +

/ +

% (reminder) + + + + + Arithmetic relational operators +

-lt (<) +

-gt (>) +

-le (<=) +

-ge (>=) +

-eq (==) +

-ne (!=) +

C programmer's should simple map the operator to its corresponding + parenthesis. + + + + + + Useful commands +

+

sed (stream editor - very useful) +

gawk +

grep (show line matching this or not matching that) +

wc (count words, lines) +

sort +

bc (more than a calculator) +

cut (edit columns) + +

It it higly recommended to be familiarized with + this programs (at least). There are tons of little + programs that will let you do real magic in a + command line. + + + + + + + + + + +More Scripts + + Applying a command to all files in a directory. +

+ + + Sample: A very simple backup script (little bit better) +

+ + #!/bin/bash + SRCD="/home/" + TGTD="/var/backups/" + OF=home-$(date +%Y%m%d).tgz + tar -cZf $TGTD$OF $SRCD + +

+ + + File re-namer +

+ + + #!/bin/sh + # renna: rename multiple files according to several rules + # written by felix hudson Jan - 2000 + + #first check for the various 'modes' that this program has + #if the first ($1) condition matches then we execute that portion of the + #program and then exit + + # check for the prefix condition + if [ $1 = p ]; then + + #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 + + # this for loop iterates through all of the files that we gave the program + # it does one rename per file given + for file in $* + do + mv ${file} $prefix$file + done + + #we now exit the program + exit 0 + fi + + # check for a suffix rename + # the rest of this part is virtually identical to the previous section + # please see those notes + if [ $1 = s ]; then + suffix=$2 ; shift ; shift + + if [$1 = ]; then + echo "no files given" + exit 0 + fi + + for file in $* + do + mv ${file} $file$suffix + done + + exit 0 + fi + + # check for the replacement rename + if [ $1 = r ]; then + + shift + + # i included this bit as to not damage any files if the user does not specify + # anything to be done + # just a safety measure + + if [ $# -lt 3 ] ; then + echo "usage: renna r [expression] [replacement] files... " + exit 0 + fi + + # remove other information + OLD=$1 ; NEW=$2 ; shift ; shift + + # this for loop iterates through all of the files that we give the program + # it does one rename per file given using the program 'sed' + # this is a sinple command line program that parses standard input and + # replaces a set expression with a give string + # here we pass it the file name ( as standard input) and replace the nessesary + # text + + for file in $* + do + new=`echo ${file} | sed s/${OLD}/${NEW}/g` + mv ${file} $new + done + exit 0 + fi + + # if we have reached here then nothing proper was passed to the program + # so we tell the user how to use it + echo "usage;" + echo " renna p [prefix] files.." + echo " renna s [suffix] files.." + echo " renna r [expression] [replacement] files.." + exit 0 + + # done! + + + + + File renamer (simple) +

+ + #!/bin/bash + # renames.sh + # basic file renamer + + 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 + + + + + +When something goes wrong (debugging) + + Ways Calling BASH +

A nice thing to do is to add on the first line + + #!/bin/bash -x + +

This will produce some intresting output information + + + + +About the document +

Feel free to make suggestions/corrections, or whatever you think + it would be interesting to see in this document. I'll try to update + it as soon as I can. + + (no) warranty +

This documents comes with no warranty of any kind. + and all that + + + Thanks to +

+ + Nathan Hurst for sending a lot of corrections. + Jon Abbott for sending comments about evaluating arithmetic expressions. + Laurent Martelli for translating this document to French (soon here the URL) + Felix Hudson for writing the + + + More resources +

+

Introduction to bash (under BE) + Bourne Shell Programming + http://207.213.123.70/book/ + + + +