Bash by Examples - LinuxIntro

download Bash by Examples - LinuxIntro

of 14

Transcript of Bash by Examples - LinuxIntro

  • 7/21/2019 Bash by Examples - LinuxIntro

    1/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 1 otp://www.linuxintro.org/wiki/BaBE

    MindMap

    BaBE - Bash By ExamplesFrom Li nuxIntroRedirec ted from BaBE)

    BaBE - Bash By Exampl es; Your signicant Linux scripting tutorial;;

    Content s

    1 Hello world2 calli ng commands3 variables

    3.1 input

    3.2 ${}3.3 com monmistakes

    4 parameter s5 return codes6 line feed s7 storing a c ommand'soutput

    7.1 $()7.2 backticks7.3 pip ing

    7.4 compar ison7.5 co mmonmistakes

    8 conditions8.1 empty strings8.2 arithmeticexpressions8.3 not equal8.4 commonmistakes

    9 Redirections10 lling les11 loops

    11.1 for loops11.2 while loops

    12 negations13 sending a process tothe background14 forking a process

    http://www.linuxintro.org/wiki/BaBE#sending_a_process_to_the_backgroundhttp://www.linuxintro.org/wiki/BaBE#sending_a_process_to_the_backgroundhttp://www.linuxintro.org/wiki/BaBE#for_loopshttp://www.linuxintro.org/wiki/BaBE#common_mistakes_3http://www.linuxintro.org/wiki/BaBE#arithmetic_expressionshttp://www.linuxintro.org/wiki/BaBE#empty_stringshttp://www.linuxintro.org/wiki/BaBE#conditionshttp://www.linuxintro.org/wiki/BaBE#common_mistakes_2http://www.linuxintro.org/wiki/BaBE#comparisonhttp://www.linuxintro.org/wiki/BaBE#pipinghttp://www.linuxintro.org/wiki/BaBE#backtickshttp://www.linuxintro.org/wiki/BaBE#.24.28.29http://www.linuxintro.org/wiki/BaBE#storing_a_command.27s_outputhttp://www.linuxintro.org/wiki/BaBE#line_feedshttp://www.linuxintro.org/wiki/BaBE#return_codeshttp://www.linuxintro.org/wiki/BaBE#parametershttp://www.linuxintro.org/wiki/BaBE#common_mistakeshttp://www.linuxintro.org/wiki/BaBE#.24.7B.7Dhttp://www.linuxintro.org/wiki/BaBE#inputhttp://www.linuxintro.org/wiki/BaBE#variableshttp://www.linuxintro.org/wiki/BaBE#calling_commandshttp://www.linuxintro.org/wiki/BaBE#Hello_worldhttp://www.linuxintro.org/index.php?title=BaBE&redirect=nohttp://www.linuxintro.org/wiki/BaBE#forking_a_processhttp://www.linuxintro.org/wiki/BaBE#sending_a_process_to_the_backgroundhttp://www.linuxintro.org/wiki/BaBE#negationshttp://www.linuxintro.org/wiki/BaBE#while_loopshttp://www.linuxintro.org/wiki/BaBE#for_loopshttp://www.linuxintro.org/wiki/BaBE#loopshttp://www.linuxintro.org/wiki/BaBE#filling_fileshttp://www.linuxintro.org/wiki/BaBE#Redirectionshttp://www.linuxintro.org/wiki/BaBE#common_mistakes_3http://www.linuxintro.org/wiki/BaBE#not_equalhttp://www.linuxintro.org/wiki/BaBE#arithmetic_expressionshttp://www.linuxintro.org/wiki/BaBE#empty_stringshttp://www.linuxintro.org/wiki/BaBE#conditionshttp://www.linuxintro.org/wiki/BaBE#common_mistakes_2http://www.linuxintro.org/wiki/BaBE#comparisonhttp://www.linuxintro.org/wiki/BaBE#pipinghttp://www.linuxintro.org/wiki/BaBE#backtickshttp://www.linuxintro.org/wiki/BaBE#.24.28.29http://www.linuxintro.org/wiki/BaBE#storing_a_command.27s_outputhttp://www.linuxintro.org/wiki/BaBE#line_feedshttp://www.linuxintro.org/wiki/BaBE#return_codeshttp://www.linuxintro.org/wiki/BaBE#parametershttp://www.linuxintro.org/wiki/BaBE#common_mistakeshttp://www.linuxintro.org/wiki/BaBE#.24.7B.7Dhttp://www.linuxintro.org/wiki/BaBE#inputhttp://www.linuxintro.org/wiki/BaBE#variableshttp://www.linuxintro.org/wiki/BaBE#calling_commandshttp://www.linuxintro.org/wiki/BaBE#Hello_worldhttp://www.linuxintro.org/index.php?title=BaBE&redirect=no
  • 7/21/2019 Bash by Examples - LinuxIntro

    2/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 2 otp://www.linuxintro.org/wiki/BaBE

    15 functions16 react on CTRL_C17 helpful programs

    17.1 awk: read aspecic column17.2 grep: search astring

    17.3 sed: replace astring17.4 tr: replacelinebreaks17.5 wc: count17.6 dialog: createdialogs

    18 See also

    Hello worldThe easiest way to get your feet wet with a programming language is to start with a program that simply outputs

    trivial text, the so-called hello-world-example. Here it is for bash:

    create a le named hello in your home directory with the following content:

    #!/bin/bash (http://en.wikipedia.org/wiki/Shebang_%28Unix%29)cho "Hello, world!"

    open a console, enter

    dhmod +x hello

    now you can execute your le like this:

    # ./helloHello, world!

    or like this:

    # bash helloHello, world!

    You see - the output of your shell program is the same as if you had entered the commands into a console.

    http://www.linuxintro.org/wiki/Programhttp://www.linuxintro.org/wiki/Open_a_consolehttp://www.linuxintro.org/wiki/Echohttp://en.wikipedia.org/wiki/Shebang_%28Unix%29http://www.linuxintro.org/wiki/BaBE#See_alsohttp://www.linuxintro.org/wiki/BaBE#dialog:_create_dialogshttp://www.linuxintro.org/wiki/BaBE#wc:_counthttp://www.linuxintro.org/wiki/BaBE#tr:_replace_linebreakshttp://www.linuxintro.org/wiki/BaBE#sed:_replace_a_stringhttp://www.linuxintro.org/wiki/BaBE#grep:_search_a_stringhttp://www.linuxintro.org/wiki/BaBE#awk:_read_a_specific_columnhttp://www.linuxintro.org/wiki/BaBE#helpful_programshttp://www.linuxintro.org/wiki/BaBE#react_on_CTRL_Chttp://www.linuxintro.org/wiki/BaBE#functions
  • 7/21/2019 Bash by Examples - LinuxIntro

    3/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 3 otp://www.linuxintro.org/wiki/BaBE

    calling commandsn your shell script you can call every command that you can call when opening a console:

    cho "This is a directory listing, latest modified files at the bottom:"s -ltr

    cho "Now calling a browser"irefoxcho "Continuing with the script"

    variables

    nput

    To show you how to deal with variables, we will now write a script that asks for your name and greets you:

    cho "what is your name? "ead namecho "hello $name"

    You see that the name is stored in a variable $name. Note the quotation marks " around "hello $name". By usinhese you say that you want variables to be replaced by their content. If you were to use apostrophes, the name

    would not be printed, but $name instead.

    ${}The ${} operator stands for the variable, there is no difference if you write

    cho "$name"

    or

    cho "${name}"

    So what is the sense of this? Imagine you want to echo a string directly, without any blank, after the content of avariable:

    cho "if I add the syllable owa to your name it will be ${name}owa"

    common mistakes

    http://www.linuxintro.org/wiki/Opening_a_console
  • 7/21/2019 Bash by Examples - LinuxIntro

    4/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 4 otp://www.linuxintro.org/wiki/BaBE

    Note that the variable is called $name, however the correct statement to read it from the keyboard is

    ead name

    t is a common mistake to write

    ead $name

    which means "read a string and store it into the variable whose name is stored in $name"

    parameters

    cho "Here are all parameters you called this script with: $@"cho "Here is parameter 1: $1"cho "Which parameter do you want to be shown? "

    ead numberrgs=("$@")cho "${args[$number-1]}"

    return codesEvery bash script can communicate with the rest of the system by

    sending data to stdout

    sending data to stderrdelivering a return code

    The return code is 0 if everything worked well. You can query it for the most recent command using $?:

    ootstick@bootstick:~$ echo "hello world"; echo $?hello world

    ootstick@bootstick:~$ echo "hello world">/proc/cmdline; echo $?ash: /proc/cmdline: Permission denied

    n bash, true is 0 and false is any value but 0. There exist two commands, true and false that deliver true or false,espectively:

    ootstick@bootstick:~$ true; echo $?

    ootstick@bootstick:~$ false; echo $?

    http://www.linuxintro.org/wiki/Stderrhttp://www.linuxintro.org/wiki/Stdout
  • 7/21/2019 Bash by Examples - LinuxIntro

    5/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 5 otp://www.linuxintro.org/wiki/BaBE

    line feedsLet's look at the following script:

    ead namef [ $name = "Thorsten" ]; then echo "I know you"; fi

    nstead of a semicolon you can write a line feed like this:

    ead namef [ $name = "Thorsten" ]

    then echo "I know you"i

    And instead of a line feed you can use a semicolon:

    ead name; if [ $name = "Thorsten" ]; then echo "I know you"; fi

    f you want to insert a line feed where you do not need one, e.g. to make the code better readable, you mustprepend it with a backslash:

    ead \name

    f [ $name = "Thorsten" ]then \

    echo "I know you"i

    storing a command's outputTo read a command's output into a variable use $(), backticks or piping.

    $()

    rch=$(uname -m)cho "Your system is a $arch system."

    backticks

    rch=`uname -m`cho "Your system is a $arch system."

    http://www.linuxintro.org/wiki/Piping
  • 7/21/2019 Bash by Examples - LinuxIntro

    6/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 6 otp://www.linuxintro.org/wiki/BaBE

    piping

    uname -m | while read arch; do echo "Your system is a $arch system."; done

    comparison

    The advantage of using backticks over $() is that backticks also work in the sh shell. The advantage of using $()over backticks is that you can cascade them. In the example below we use this possibility to get a list of all lesnstalled with rpm on the system:

    ilelist=$(rpm -ql $(rpm -qa))

    You can use the piping approach if you need to cascade in sh, but this is not focus of this bash tutorial.

    common mistakesUsually unexperienced programmers try something like

    uname -m | read arch

    which does not work (http://mywiki.wooledge.org/BashFAQ/024) . You must embed the read into a while loop.

    conditionsThe easiest form of a condition in bash is this if example:

    cho "what is your name? "ead namef [ $name = "Thorsten" ]; then echo "I know you"; fi

    Now let's look closer at this, why does it work? Why is there a blank needed behind the [ sign? The answer ishat [ is just an ordinary command in the shell. It delivers a return code for the expression that follows till the ]

    ign. To prove this we can write a script:

    f true; then echo "the command following if true is being executed"; fif false; then echo "this will not be shown"; fi

    empty strings

    http://www.linuxintro.org/wiki/Commandhttp://mywiki.wooledge.org/BashFAQ/024http://www.linuxintro.org/wiki/Rpm
  • 7/21/2019 Bash by Examples - LinuxIntro

    7/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 7 otp://www.linuxintro.org/wiki/BaBE

    An empty string evaluates to false inside the [ ] operators so it is possible to check if a string result is empty likhis:

    weedleburg:~ # result=weedleburg:~ # if [ $result ]; then echo success; fiweedleburg:~ # result=goodweedleburg:~ # if [ $result ]; then echo success; fiuccess

    arithmetic expressions

    cho "what is your age? "ead agef (( $age >= 21 )); then echo "Let's talk about sex."; fi

    not equal

    To check if a variable is NOT equal to whatever, use !=:

    f [ "$LANG" != "C" ]; then echo "please set your system lanugage to C"; fi

    common mistakes

    Common mistakes are:

    to forget the blank behind/before the [ or ] characterto forget the blank behind/before the equal signsee what does "unary operator expected" mean

    RedirectionsTo redirect the output of a command to a le you have to consider that there are two output streams in UNIX,tdout and stderr.

    lling lesTo create a le, probably the easiest way is to use cat. The following example writes text into README till aine occurs that only contains the string "EOF":

    at >README

  • 7/21/2019 Bash by Examples - LinuxIntro

    8/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 8 otp://www.linuxintro.org/wiki/BaBE

    This is line 2This is the last lineEOF

    Afterwards, README will contain the 3 lines below the cat command and above the line with EOF.

    loopsfor loops

    Here is an example for a for-loop. It makes a backup of all text les:

    or i in *.txt; do cp $i $i.bak; done

    The above command takes each .txt le in the current directory, stores it in the variable $i and copies it to $i.bak.

    So le.txt gets copied to le.txt.bat.

    You can also use subsequent numbers as a for loop using the command seq like this:

    or i in $(seq 1 1 3); do echo $i; done

    while loops

    while true; do read line; done

    negationsYou can negate a result with the ! operator. $? is the last command's return code:

    # true# echo $?

    # false

    # echo $?

    # ! true# echo $?

    # ! false# echo $?

    So you get an endless loop out of:

    http://www.linuxintro.org/wiki/Echohttp://www.linuxintro.org/wiki/Seqhttp://www.linuxintro.org/wiki/Variablehttp://www.linuxintro.org/wiki/Cphttp://www.linuxintro.org/wiki/Backup
  • 7/21/2019 Bash by Examples - LinuxIntro

    9/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 9 otp://www.linuxintro.org/wiki/BaBE

    hile ! false; do echo hallo; done

    The following code checks the le /tmp/success to contain "success". As long as this is not the case it continuehecking:

    hile ! (grep "success" /tmp/success)

    dosleep 30done

    The following code checks if the le dblog.log exists. As long as this is not the case it tries to download it via ftp:

    hile ! (test -e dblog.log); doftp -p ftp://user:password@server/tmp/dblog.log >/dev/nullecho -en "."sleep 1

    done

    sending a process to the backgroundTo send a process to the background, use the ampersand sign (&):

    irefox & echo "Firefox has been started"

    You see a newline is not needed after the &

    forking a processYou can build a process chain using parantheses. This is useful if you want to have two instruction streams beingxecuted in parallel:

    find -iname "helloworld.txt") & (sleep 5; echo "Timeout exceeded, killing process"; kill $!)

    functionsTo dene a function in bash, use a non-keyword and append opening and closing parentheses. Here a functiongreet is dened and it prints "Hello, world!". Then it is called:

    greet()

    echo "Hello, world!"

    http://www.linuxintro.org/wiki/Backgroundftp://user:password@server/tmp/dblog.log
  • 7/21/2019 Bash by Examples - LinuxIntro

    10/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 10 otp://www.linuxintro.org/wiki/BaBE

    greet

    react on CTRL_CThe command trap allows you to trap CTRL_C keystrokes so your script will not be aborted

    #!/bin/bash

    rap shelltrap INT

    helltrap()

    echo "You pressed CTRL_C, but I don't let you escape"

    hile true; do read line; done

    NoteYou can still pause your script by pressing CTRL_Z, send it to the background and kill it there. To catchCTRL_Z, replace INT by TSTP in the above example. To get an overview of all signals that you might beable to trap, open a console and enter

    kill -l

    helpful programs

    awk: read a specic column

    wk is a program that is installed on almost all Linux distributions. It is a good helper for text stream processing.t can extract columns from a text. Let's imagine you want to use the program vmstat to nd out how high the

    CPU user load was. Here is the output from vmstat:

    rocs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------r b swpd free buff cache si so bi bo in cs us sy id wa st1 0 0 1304736 190232 885840 0 0 20 8 11 17 1 0 99 0 0

    We see the user load is in colum 13, and we only want to print this column. We do it with the followingommand:

    vmstat 5 | awk '{print $13}'

    This will print a line from vmstat all 5 seconds and only write the column 13. It looks like this:

    http://www.linuxintro.org/wiki/Vmstathttp://www.linuxintro.org/wiki/Programhttp://www.linuxintro.org/wiki/Awkhttp://www.linuxintro.org/wiki/Open_a_consolehttp://www.linuxintro.org/wiki/Background
  • 7/21/2019 Bash by Examples - LinuxIntro

    11/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 11 otp://www.linuxintro.org/wiki/BaBE

    # vmstat 5 | awk '{print $13}'

    us

    To store the CPU user load into a variable we use

    oad=$(vmstat 1 2 | tail -n 1 | awk '{print $13}')

    What happens here? First vmstat outputs some data in its rst line. The data about CPU load can only be rubbishbecause it did not have any time to measure it. So we let it output 2 lines and wait 1 second between them ( =>vmstat 1 2 ). From this command we only read the last line ( => tail -n 1 ). From this line we only print column3 ( => awk '{print $13}' ). This output is stored into the variable $load ( => load=$(...) ).

    grep: search a stringgrep is a program that is installed on almost all Linux distributions. It is a good helper for text stream processing.t can extract lines that contain a string or match a regex pattern. Let's imagine you want all external links from

    www.linuxintro.org's main page:

    get -O linuxintro.txt http://www.linuxintro.orggrep "http:" linuxintro.txt

    sed: replace a stringed is a program that is installed on almost all Linux distributions. It is a good helper for text stream processing.t can replace a string by another one. Let's imagine you want to print your distribution's name, but lsd_release

    outputs too much:

    # lsb_release -dDescription: openSUSE 12.1 (x86_64)

    You want to remove this string "Description" so you replace it by nothing:

    sb_release -d | sed "s/Description:\t//"penSUSE 12.1 (x86_64)

    Once you understand regular expressions you can use sed with them:

    to replace protocol names for a given port (in this case 3200) in /etc/services:

    http://www.linuxintro.org/wiki/Regular_expressionshttp://www.linuxintro.org/wiki/Programhttp://www.linuxintro.org/wiki/Sedhttp://www.linuxintro.org/http://www.linuxintro.org/wiki/Regexhttp://www.linuxintro.org/wiki/Programhttp://www.linuxintro.org/wiki/Grep
  • 7/21/2019 Bash by Examples - LinuxIntro

    12/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 12 otp://www.linuxintro.org/wiki/BaBE

    ed -ri "s/.{16}3200/sapdp00 3200/" /etc/services

    if you have an apache web server here's how you get the latest websites that have been requested:

    r: replace linebreaks

    ed is a program that is installed on almost all Linux distributions. It is a good helper for text stream processing.t can replace a character by another one, even over line breaks. For example here is how you remove all emptyines from your processor information:

    wc: countWith the command wc you can count words, characters and lines. wc -l counts lines. For example to nd out howmany semicolons are in a line, use the following statement:

    hile read line; do echo "$line" | tr '\n' ' ' | sed "s/;/\n/g" | wc -l; done

    t lets you input a line of text, counts the semicolons in it and outputs the number.

    How does it do this?

    t reads lines from your keyboard (while read line). It outputs the line (echo "$line"), but it does not output it inhe console. The pipe (|) redirects the output to the input stream of the command tr. The command tr replaces the

    ENTER ('\ ') by a space (' '). The pipe (|) redirects the output to the input stream of sed. sed substitutes ("s/) theemicolon (;) by (/) a linefeed (\ ), globally (/g"). The pipe redirects the output to the input stream of the wc -lommand that outputs the count of lines.

    dialog: create dialogs

    Dialog is a command that helps you creating dialogs in the shell. The answers given by the user are send to stderrnd/or inuence the command's return code. For example if you run this script:

    #!/bin/bashf (dialog --title "Message" --yesno "Are you having fun?" 6 25)hen echo "glad you have fun"lse echo "sad you don't have fun"i

    at /var/log/apache2/access_log | sed "s;.*

  • 7/21/2019 Bash by Examples - LinuxIntro

    13/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 13 otp://www.linuxintro.org/wiki/BaBE

    t will display this dialog:

    This has been taken from http://www.linuxjournal.com/article/2807. Read there for more info.

    See alsobashshellscriptingbash operatorshttp://en.wikibooks.org/wiki/Bash_Shell_Scriptinghttp://ryanstutorials.net/linuxtutorial/scripting.phphttp://wiki.linuxquestions.org/wiki/Bash_tipshttp://wiki.linuxquestions.org/wiki/Bashhttp://linuxcong.org/Bash_scripting_Tutorialhttp://steve-parker.org/sh/intro.shtmlhttp://mywiki.wooledge.org/BashFAQhttp://mywiki.wooledge.org/BashPitfalls

    Facebook social plugin

    Also post on Facebook

    Posting as Laith Al Obaidy ! Comment

    Add a comment...

    https://www.facebook.com/plugins/comments.php?api_key=203018859828162&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FKvoNGODIqPG.js%3Fversion%3D41%23cb%3Df1d600a8d4%26domain%3Dwww.linuxintro.org%26origin%3Dhttp%253A%252F%252Fwww.linuxintro.org%252Ff3d85a49bc%26relation%3Dparent.parent&colorscheme=light&href=http%3A%2F%2Fwww.linuxintro.org%2Fwiki%2FBaBE%20-%20Bash%20By%20Examples&locale=en_US&numposts=5&sdk=joey&skin=light&width=470#https://www.facebook.com/plugins/comments.php?api_key=203018859828162&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FKvoNGODIqPG.js%3Fversion%3D41%23cb%3Df1d600a8d4%26domain%3Dwww.linuxintro.org%26origin%3Dhttp%253A%252F%252Fwww.linuxintro.org%252Ff3d85a49bc%26relation%3Dparent.parent&colorscheme=light&href=http%3A%2F%2Fwww.linuxintro.org%2Fwiki%2FBaBE%20-%20Bash%20By%20Examples&locale=en_US&numposts=5&sdk=joey&skin=light&width=470#https://developers.facebook.com/docs/plugins/?footer=1https://developers.facebook.com/docs/plugins/?footer=1http://mywiki.wooledge.org/BashPitfallshttp://mywiki.wooledge.org/BashFAQhttp://steve-parker.org/sh/intro.shtmlhttp://linuxconfig.org/Bash_scripting_Tutorialhttp://wiki.linuxquestions.org/wiki/Bashhttp://wiki.linuxquestions.org/wiki/Bash_tipshttp://ryanstutorials.net/linuxtutorial/scripting.phphttp://en.wikibooks.org/wiki/Bash_Shell_Scriptinghttp://www.linuxintro.org/wiki/Bash_operatorshttp://www.linuxintro.org/wiki/Scriptinghttp://www.linuxintro.org/wiki/Shellhttp://www.linuxintro.org/wiki/Bashhttp://www.linuxjournal.com/article/2807http://www.linuxintro.org/wiki/File:Snapshot-dialog.png
  • 7/21/2019 Bash by Examples - LinuxIntro

    14/14

    4/27/15, 3:10 PaBE - Bash By Examples - LinuxIntro

    Page 14 otp://www.linuxintro.org/wiki/BaBE

    Retrieved from "http://www.linuxintro.org/index.php?title=BaBE_-_Bash_By_Examples&oldid=19055"Category: Learning

    This page was last modied on 12 April 2015, at 09:47.This page has been accessed 9,881 times.

    http://googleads.g.doubleclick.net/aclk?sa=l&ai=Ct607OpY-VZSMCcyEpgPLl4C4CYiPqvwJyOqMl7ACuLr04OgBEAEgAGDJ1oOI8KPsEoIBF2NhLXB1Yi01OTg2NDM1NTY4NTM2NDkwoAGYmuG-A8gBAqgDAcgDwQSqBI4BT9DnhXaCEgXSNFGvZW305IebgtvTRxBkAqGbeJh5G0tuBL0IF1GPk3qti9s-T42NGYeiEftOY_nTrWhUUBJSApFTkGsOCm1hn_ESABN3WdrprWdBrzkD08UHaiKiNocOiEX4Ne49O73n3hpknsOXHOYWebD8censSm5iv-8l-3p3M7spImZhBoB04giSs6AGAtgHAA&num=1&sig=AOD64_1zi_0eIkY_D6EbhC9jKrVcErUJBQ&client=ca-pub-5986435568536490&adurl=http://catalogicsoftware.com/en/products/trial/http://www.linuxintro.org/wiki/Special:Categorieshttp://www.linuxintro.org/index.php?title=BaBE_-_Bash_By_Examples&oldid=19055http://www.linuxintro.org/index.php?title=Category:Learning&action=edit&redlink=1