Bash scripting 101: Chapter 4: IF he's jolly why is he loopy? (loopy loops)





we ended last chapter with a script to look if a hostname exists with different tld's

we'll start this one with one that can do international tld's as well

#!/bin/bash
test "${1}" = "" && echo 'script needs at least a domain name without tld to check' && exit 1

ORIGINAL_TLD="edu com gov net org"
INTERNATIONAL_TLD="se dk de uk us"
TOPLEVELDOMAINS="$ORIGINAL_TLD $INTERNATIONAL_TLD"

for TLD in $TOPLEVELDOMAINS
do
    host $1.$TLD
done

nothing new there actually, we just combined something from scripts on the earlier page :-)

what if you want more international tld's?..just add them to INTERNATIONAL_TLD, what if you want one not in the list and don't want it NORMALLY in the variable/list(INTERNATIONAL_TLD) (that list is checked every time you run it, so it can get a bit much) ie..what if you just want to add "nu" tld for one time only?

well you can do that too

#!/bin/bash
test "${1}" = "" && echo 'script needs at least a domain name without tld to check' && exit 1

LOOKMEUP=$1

shift

ORIGINAL_TLD="edu com gov net org"
INTERNATIONAL_TLD="se dk de uk us"

for EXTRATLD in $@
do
    MORETLD="$MORETLD $EXTRATLD"
    shift
done

TOPLEVELDOMAINS="$ORIGINAL_TLD $INTERNATIONAL_TLD $MORETLD"

for TLD in $TOPLEVELDOMAINS
do
    host $LOOKMEUP.$TLD
done
exit 1

SCREAM!!! you MAD person!!! you are trying to give me a headache..i KNEW it!

not at all, look how few "new" things are actually there? i'll just do explanations of the new and/or (in shellscripter parlance..(&&/||) )"complex stuff". ok..i'm sorry that shellscripter parlance was a bad joke

  1. #!/bin/bash
    shebang line, (old news)

  2. test "${1}" = "" && echo 'script needs at least a domain name without tld to check' && exit 1
    check for commandline arguments or exit with error message and code (old news)

  3. LOOKMEUP=$1
    move first command line argument into LOOKMEUP variable (old news)

  4. shift
    AHA! NEWS! shift moves the $1 one step, it repositions the contents of $@ by one (read the bash man file on shift)

    in this case it moves host_2_lookup argument that we give the shellscript out of the way giving us access to the rest of the potential arguments

    ie it makes/moves the content of $2 into $1, the content of $3 into $2 and so forth

  5. ORIGINAL_TLD="edu com gov net org"
    set the original tld's into variagle ORIGINAL_TLD (old news)

  6. INTERNATIONAL_TLD="se dk de uk us"
    put some international ones into INTERNATIONAL_TLD (old news)

  7. for EXTRATLD in $@
    uh oh!...for every value in $@ (which contains a list of command line arguments) put the value into EXTRATLD...NOTE remember we 'shift'ed the $@ by one step above (point 4)

  8. do
    ancient news, starts the do block

  9. MORETLD="$MORETLD $EXTRATLD"
    MORETLD is the same as contents of MORETLD and the contents of EXTRATLD
    so the first time it's empty and gets the first TLD you gave as second argument, then it's got the second argument and gets the third, and so forth

  10. shift
    move the arguments in $@ one step so we keep grabbing a new one

  11. done
    end the for/do/done block

  12. TOPLEVELDOMAINS="$ORIGINAL_TLD $INTERNATIONAL_TLD $MORETLD"
    put into TOPLEVELDOMAINS the content of all our TLD's

  13. for TLD in $TOPLEVELDOMAINS
    (old news)

  14. do
    (old news)

  15. host $LOOKMEUP.$TLD
    (old news)

  16. done
    (old news)

  17. exit 0
    exit this script with a 0 (completed successfully) in case we run this script from another script

now was that really so painful?

ok what about if you optionally want to pass an argument to the program "host"? say "-v" or "-t querytype"

it's doable too:

#!/bin/bash
test "${1}" = "" && echo -e "script needs at least a domain name without tld to check it also accepts -v and -t type switches equivalent to host commands -v -t type, ie\n $0 host2lookup -v -t type\n alt $0 host2lookup -t type -v\n any argument after the first (host2lookup) that is not -v or -t type\n is considered a tld\n ie nu es fi uk us\n" && exit 1

LOOKMEUP=$1
SHIFTCOUNT=0

if test "${2}" = "-v" && test "${3}" = "-t"
    then
        ARGUMENT="-v -t $4"
        let SHIFTCOUNT=$SHIFTCOUNT+4
    elif test "${2}" = "-v"
    then
        ARGUMENT="-v"
        let SHIFTCOUNT=$SHIFTCOUNT+2
    elif test "${2}" = "-t" && test "${4}" = "-v"
    then
        ARGUMENT="-v -t $3"
    let SHIFTCOUNT=$SHIFTCOUNT+4
    elif test "${2}" = "-t"
    then
        ARGUMENT="-t $3"
        let SHIFTCOUNT=$SHIFTCOUNT+3
fi

if test $SHIFTCOUNT = 0
    then
# you may have to replace "let SHIFTCOUNT++" below, with "let SHIFTCOUNT=$SHIFTCOUNT+1"
# depending on bash version 2.05 handles below, my 2.03 does NOT
    let SHIFTCOUNT++
fi


shift $SHIFTCOUNT


ORIGINAL_TLD="edu com gov net org"
INTERNATIONAL_TLD="se dk de uk us"

for EXTRATLD in $@
do
    MORETLD="$MORETLD $EXTRATLD"
    shift
done

TOPLEVELDOMAINS="$ORIGINAL_TLD $INTERNATIONAL_TLD $MORETLD"

for TLD in $TOPLEVELDOMAINS
do
    host $ARGUMENT $LOOKMEUP.$TLD
done

oookayyyyyy!!! you can stop screaming at me now! go out, have a coffee or a smoke or what ever, come back in 5 minutes with fresh bloodsugar and some fresh air :-)

ready? let's rock!

  1. #!/bin/bash
    shebang line (old news)

  2. test "${1}" = "" && echo -e "script needs at least a domain name without tld to check it also accepts -v and -t type switches equivalent to host commands -v -t type, ie\n $0 host2lookup -v -t type\n alt $0 host2lookup -t type -v\n any argument after the first (host2lookup) that is not -v or -t type\n is considered a tld\n ie nu es fi uk us\n" && exit 1
    if we don't get at least one argument, throwback help at the user then quit (exit) with an "error" (1), one thing worth noticing is the use of $0, the name the script got calledby is here, so if you call it "bla" it'll be bla, and if you call it "ifdomain" it'll be ifdomain

  3. LOOKMEUP=$1
    grab the host2lookup from commandline argument 1($1) and put it into LOOKMEUP variable

  4. SHIFTCOUNT=0
    set a counter for "shift", we want to shift the commandline arguments a bit if we have "-t type" or "-v" or even "-t type -v es" for instance. Set this counter to "0" to begin with

  5. if test "${2}" = "-v" && test "${3}" = "-t"
    NEWS! "IF" or rather ..if command/then command/elif command/then command/else commands/fi

    when you've stopped screaming at me you can go on reading :-)

    it's quite simple if put in a logical way:

    IF thisherecommand/expression is true(exit status 0)
    THEN execute this command
    ELIF (else if/if the previous didn't match) AND this_here_other_command/otherexpression is true
    THEN execute this other command
    ELSE (if none of the previous ones matched) do this command instead
    FI end the "IF" block

    the only thing that's important to remember is that it's the exit status of the program, ie not the number,

    "test 0 = 0" will exit with (0)
    "test 1 = 0" will exit with (1) because it's not so
    but
    "test 0 != 0" will exit with (1), because "!" before an expression means "NOT" so you are actually saying "test if 0 is NOT equal to zero, if it is equal, return FALSE (exit with error (1)) if it's NOT equal return true (exit with success (0))

    this is boolean logic in a fashion but it depends on the exit status of the "program"/"command being run" and thus "help exit" and "help test" will be of great use to you

    so basically what i am telling the script is...if second commandline argument "${2}" is "-v" AND (remember "&&" means "AND") third commandline argument "${3} is "-t" do the block after the next "then"

  6. then
    start the block to do if the first "if" evaluated as true (exited with 0)

  7. ARGUMENT="-v -t $4"
    put into the variable "ARGUMENT" the quoted string "-v -t $4" looking at the help message for this script and "man host" we see that "-t querytype" is the syntax thus -t should be followed by something like ANY or MX, and if:
    $1 is taken by host2lookup
    $2 is taken by -v (which we checked for)
    $3 is taken by -t (which we also checked for
    $4 should contain the type (if the user follows command syntax, if not, then ESBK (error sits behind keyboard)

  8. let SHIFTCOUNT=$SHIFTCOUNT+4
    add "4" to the "0" of SHIFTCOUNT variable "host2lookup" "-v" "-t" "type" takes up 4 commandline arguments

  9. elif test "${2}" = "-v"
    if the first one(point 5) wasn't true is this one? is the second commandline argument -v?

  10. then
    this one is old news by now...start the second "conditional block" if the previous point was true

  11. ARGUMENT="-v"
    set the variable ARGUMENT to "-v"

  12. let SHIFTCOUNT=$SHIFTCOUNT+2
    add 2 to the 0 inside SHIFTCOUNT variable "host2lookup" and "-v" takes up 2 commandline arguments

  13. elif test "${2}" = "-t" && test "${4}" = "-v"
    does $2 contain -t AND $4 contain -v? (WHOA..why did i jump $3? ..remember syntax? "-t type" that's why! if user follows syntax then $3 MUST contain type

  14. then
    you know this one by now

  15. ARGUMENT="-v -t $3"
    set variable ARGUMENT to contain "-v -t $3" i could have set it to contain "-t $3 -v" but i prefer to keep it in one order (no particular reason really), it's just like me using "ls -la" and some use "ls -al" same effect, different order of switches

  16. let SHIFTCOUNT=$SHIFTCOUNT+4
    set SHIFTCOUNT to contain 4 (0+4=4) "host2lookup -t type -v" $1,$2,$3,$4 being used

  17. elif test "${2}" = "-t"
    is commandline argument 2 "-t"?

  18. then
    *tosses up hands* i'm not touching this one!

  19. ARGUMENT="-t $3"
    set variable ARGUMENT to "-t $3" syntax is still -t type, "hostname2lookup -t type" puts type in $3

  20. let SHIFTCOUNT=$SHIFTCOUNT+3
    make SHIFTCOUNT variable 3 (see previous point...3 arguments 3 shifts)

  21. fi
    end the "if". fi ends if, it's just if spelled backwards (c'mon everyone saw that one coming right?)

  22. if test $SHIFTCOUNT = 0
    if $SHIFTCOUNT didn't get anything above, that means we only have hostname2lookup as a commandline argument

  23. then
    old news

  24. # ...
    in "program" comments to help people using the program (soon i'll do all explaining there, except for the advanced stuff which i'll break down in lists like before)

  25. let SHIFTCOUNT++
    aha ..."++" whadda ya mean "++"??? VARIABLE++ is a simple way if saying "add one to this one", there also exists ++VARIABLE, and --VAR and VAR--, if the ++ are before, then 1 is added to the variable BEFORE an eventual evaluation, if it's after then it's done AFTER

    this one shouldn't be neccessary "shift" automatically assumes that it shifts from 1

    but since i'm later using "shift $SHIFTCOUNT" and SHIFTCOUNT is set to 0, then i'd get a repeat of 1 if i didn't do this

    this "if/fi" block could be replaced with (untested)

    if test $SHIFTCOUNT < 1
    then
    shift 2
    else
    shift $SHIFTCOUNT
    fi

    i find my small if and then a standard way to handle it easier to debug

  26. fi
    end the "if block"

  27. shift $SHIFTCOUNT
    shift.. (see previous scripts) move the $1-"$what ever" that we've used for hostname2lookup eventual "-v" "-t" and "type" out of the way, giving us access to the rest of them easily

  28. ORIGINAL_TLD="edu com gov net org"
    put the 5 of the original tld's into ORIGINAL_TLD variable

  29. INTERNATIONAL_TLD="se dk de uk us"
    put "se dk de uk us" into the INTERNATIONAL_TLD variable

  30. for EXTRATLD in $@
    for every commandline argument after what WAS prior to point 26 $1-$4 (which ever many we had) put this new one into EXTRATLD

  31. do
    old news, starts the for "do" block

  32. MORETLD="$MORETLD $EXTRATLD"
    MORETLD is equal to the contents of MORETLD variable and EXTRATLD, so if MORETLD is empty "" and EXTRA TLD this time around has "es", MORETLD becomes """es" which is in fact "es"

    if the next value in $@ after the "es" is "uk" then it becomes MORETLD="es EXTRATLD" ie MORETLD="es uk" and so forth

  33. shift
    each time the previous point runs, shift the commandline one step, (this one shouldn't really be needed), try commenting it out if you want

  34. done
    heh really antique news

  35. TOPLEVELDOMAINS="$ORIGINAL_TLD $INTERNATIONAL_TLD $MORETLD"
    put into TOPLEVELDOMAINS variable, the original TLD's, the INTERNATIONAL ones, and what ever extra ones user defined on the commandline

  36. for TLD in $TOPLEVELDOMAINS
    for every value in TOPLEVELDOMAINS variable execute the below block of commands do-done

  37. do
    old news

  38. host $ARGUMENT $LOOKMEUP.$TLD
    host (the host command) $ARGUMENT put in eventual command line arguments (like -t type or -v or both). $LOOKMEUP which contains host2lookup and then .$TLD. a dot and the TLD variable that gets the value of the current "element" from TOPLEVELDOMAIN

  39. done
    end for-do-done

  40. exit 0
    exit with success (0)

ok that's schools out for today signal..scoot on home, take this with ya, and return later rested, refreshed and having experimented and i'll try to put up some more chapters




Bash Scripting101: Chapter 3: For he'$ a jolly good fellow (loopy loops) Bash scripting 101: Chapter 5: WHILE we are at it and UNTIL we are done(more loopy loops)



w0nderer