Updated October 23, 2004
Created October 12, 2004


Autogenerated Site Map
Search this Site!:
Search this site powered by FreeFind


This builds on the "Variable Indirection" found later on this page.

I actually got a trailing "_VALIDATION" to stick to several individual indirect variables:
     64 validate_variables()
     65 {
     66 for VARIABLE_ITEM in $VARIABLE_LIST; do
# Snips off a default value which starts at =.*$
     67         VARIABLE_ITEM=`echo $VARIABLE_ITEM | sed -e 's/=.*$//'`
     68         if [ -n "${!VARIABLE_ITEM}" ]; then
# I am pulling preconfigured grep entries from a flat file which contains ^, $, and \| (beginning, end, or).
     69                 GREPCMD=`cat field-validation.txt | grep ^$VARIABLE_ITEM | head -1 | sed -e "s/^$VARIABLE_ITEM *\t*//"`
# validate variable with its given grep command
     70                 echo ${!VARIABLE_ITEM} | grep $GREPCMD >/dev/null 2>&1 && {
     71                 # Validation passed
     72                 export ${VARIABLE_ITEM}_VALIDATION=1
     73                 } || {
     74                 # Validation failed
     75                 export ${VARIABLE_ITEM}_VALIDATION=0
     76                 echo sorry item $VARIABLE_ITEM did not pass validation
     77                 }
     78 set | grep -i VALIDATION
     79 exit
     80         fi
     81 done
     82 }
Output:
SERIALNUMBER_VALIDATION=0
... other snipped garbage ...
So this means I can build all kinds of indirect variables where I identify items such as their default value and stick it into VariableName_DEFAULT, etc. It is almost like an array where the actual variable name is the handle (index/key, whatever the call it).

I will use this "validation result" later on when displaying the page to determine if I need to flag it for user attention.

Ok, trying to use it with just plain Bash parameter expansion. I haven't figured that one out just yet. Any ideas? Well, here is what I am using in the mean time - I know there has to be a way to bend bash to do a 2nd pass scan, just can't think of it:
     96         if [ "`set | grep ^${VARIABLE_ITEM}_VALIDATION= | sed -e 's/^.*=//'`" = "1" ]; then
     97                 echo -n '<font color="red">'
     98         fi

     101        if [ "`set | grep ^${VARIABLE_ITEM}_VALIDATION= | sed -e 's/^.*=//'`" = "1" ]; then
     102                echo -n '</font>'
     103        fi

Bash debugging

This turns on debugging for your entire script:
#!/bin/bash -x

Or in your body of code you need to debug:
... normal code ...
set -o xtrace
# tracing is now turned on...
... buggy code to debug ...
set +o xtrace
# trace is now turned off...
... normal code ...

When debugging bash (-x or xtrace), the number of leading plus signs shows if you are in a subshell or not. It shows you the level of subshells deep the commands are operating. Example, here is a single run of a for loop snippet. Notice how the double plus signs (++) correspond with the backticks (backticks open up a subshell):


++ echo UNITNUM
++ sed -e 's/=.*$//'
+ VARIABLE_ITEM=UNITNUM

+ echo -n '<tr><td>'

++ set
++ sed -e 's/^.*=//'
++ grep '^UNITNUM_VALIDATION='
+ '[' -1 = 1 ']'

+ grep UNITNUM
+ head -1
+ read ONE TWO
+ cat field-wording.txt
+ echo -n Unit Number:
+ read ONE TWO

++ set
++ grep '^UNITNUM_VALIDATION='
++ sed -e 's/^.*=//'
+ '[' -1 = 1 ']'

+ echo -n '</td><td>'

+ echo -n '<input type=text name="'

+ echo -n UNITNUM
+ tr '[:upper:]' '[:lower:]'

+ echo -n '" value="'

+ echo -n ''

+ echo -n '">'

+ echo '</td></tr>'
    280 for VARIABLE_ITEM in $VARIABLE_LIST; do

    281         VARIABLE_ITEM=`echo $VARIABLE_ITEM | sed -e 's/=.*$//'`



    282         echo -n "<tr><td>"

    283         if [ "`set | grep ^${VARIABLE_ITEM}_VALIDATION= 
	| sed -e 's/^.*=//'`" = "1" ]; then
    284                 echo -n '<font color="red">'
    285         fi

    286         cat field-wording.txt | grep $VARIABLE_ITEM | head -1 
	| while read ONE TWO; do echo -n $TWO; done





    287         if [ "`set | grep ^${VARIABLE_ITEM}_VALIDATION= 
	| sed -e 's/^.*=//'`" = "1" ]; then
    288                 echo -n '</font>'
    289         fi

    290         echo -n "</td><td>"

    291         echo -n "<input type=text name=\""

    292         echo -n $VARIABLE_ITEM | tr [:upper:] [:lower:]


    293         echo -n "\" value=\""

    294         echo -n "${!VARIABLE_ITEM}"

    295         echo -n "\">"

    296         echo "</td></tr>"

    297 done
I word wrapped 3 of the above lines (283, 286, and 287)
VAR=VALUE
export VAR=VALUE

Variable Scope - Ok items: for, while, if, &&, ||, {}, functions
for X in 1; do VARPLAIN=forloop; export VAREXPORT=forloop; done; echo $VARPLAIN; echo $VAREXPORT
while :; do VARPLAIN=aaa; export VAREXPORT=abc; break; done; echo $VARPLAIN; echo $VAREXPORT 
{ while :; do VARPLAIN=111; export VAREXPORT=222; break; done; }; echo $VARPLAIN; echo $VAREXPORT
if [ 1 -eq 1 ]; then { while :; do VARPLAIN=777; export VAREXPORT=888; break; done; }; fi; echo $VARPLAIN; echo $VAREXPORT
echo hi | grep hi >/dev/null && { VARPLAIN=22222; export VAREXPORT=44444; }; echo $VARPLAIN; echo $VAREXPORT
echo $HI; myfunc(){ HI=3;}; myfunc; echo $HI
Variable Scope is lost when a subshell is used: (), |, ``

Parenthesis, pipes, and backticks open up subshells:
( while :; do VARPLAIN=333; export VAREXPORT=444; break; done; ); echo $VARPLAIN; echo $VAREXPORT
( VARPLAIN=999; export VAREXPORT=101; ); echo $VARPLAIN; echo $VAREXPORT 
echo hellothere | while read; do VARPLAIN=555; export VAREXPORT=678; break; done; echo $VARPLAIN; echo $VAREXPORT
echo $HI; echo `echo setting HI in backticks; HI=hello; echo Value inside backticks $HI`; echo Value outside: $HI

Bash Variable Indirection - Setting and accessing variables indirectly

# List of variables I want to create and manipulate:
VARIABLE_LIST="
SERIALNUMBER
ASSETTAG
MACADDR1
MACADDR2
RACKNUM
UNITNUM
IPADDRESS
"
# Simple for loop to set each variable to "hello":
for VARIABLE_ITEM in $VARIABLE_LIST; do
        echo Working on $VARIABLE_ITEM
	export ${VARIABLE_ITEM}=hello
        echo Item is: ${VARIABLE_ITEM}
        echo Item Value is: ${!VARIABLE_ITEM}
done
# Proof that these variables are now in the environment:
set

# Ok, the above explains well, but does not show why you would want such a thing.
# I have a list of variables I want treated equally.  They will drive the creation
# of various web pages.  I don't want to create many needless lines of duplicate
# code - all doing the same thing, just with different variables -- not to mention
# if I goof a line.
# Here is one of the original for loops manipulating them as part of a cgi script in progress:
for VARIABLE_ITEM in $VARIABLE_LIST; do
        VARIABLE_ITEM_LOWER=`echo $VARIABLE_ITEM | tr [:upper:] [:lower:]`
        echo $VARIABLE_ITEM
        echo $VARIABLE_ITEM_LOWER
# Set the individual variable
	export ${VARIABLE_ITEM}=`echo $MYVAR | tr '&' '\n' | grep $VARIABLE_ITEM_LOWER | sed -e "s/$VARIABLE_ITEM_LOWER=//g"`
# Display which variable I set
        echo Item is ${VARIABLE_ITEM}
# Display the value of the variable I set
        echo Item Value is ${!VARIABLE_ITEM}
done
# Proof that the variable is indeed set and has a particular value...
set

# For a better understanding of what I am pulling out of $MYVAR, look inside http://www.cpqlinux.com/cal.cgi

Bash supports more than 0 - 9 positional parameters. Access them via:
$0, $1, ... $9, ${10}, ..., ${15}, ...

Handling filenames with spaces:

This cp command won't handle spaces in the filenames:
for X in `find . -type f -name '*html'`; do cp -al "$X" /tmp/html/; done

This cp command will handle filenames with spaces:
find . -type f -name '*html' | while read; do cp -al "$REPLY" /tmp/html/; done

Search this Site!:
Search this site powered by FreeFind

Homepage: http://www.cpqlinux.com
Site Map: http://www.cpqlinux.com/sitemap.html