Enable NET-SNMP-PASS-MIB.txt - net-snmp

I'm trying to use the MIB-Specific Extension Commands of the SNMP protocol.
I have an snmpd agent running in an Embedded Linux environment. In snmpd.conf I've uncommented the following line:
pass .1.3.6.1.4.1.2021.255 /bin/sh /usr/local/passtest
The /usr/local/passtest looks like this:
#!/bin/sh -f
PLACE=".1.3.6.1.4.1.2021.255" # NET-SNMP-PASS-MIB::netSnmpPassExamples
REQ="$2" # Requested OID
#
# Process SET requests by simply logging the assigned value
# Note that such "assignments" are not persistent,
# nor is the syntax or requested value validated
#
if [ "$1" = "-s" ]; then
echo $* >> /tmp/passtest.log
exit 0
fi
#
# GETNEXT requests - determine next valid instance
#
if [ "$1" = "-n" ]; then
case "$REQ" in
$PLACE| \
$PLACE.0| \
$PLACE.0.*| \
$PLACE.1) RET=$PLACE.1.0 ;; # netSnmpPassString.0
$PLACE.1.*| \
$PLACE.2| \
$PLACE.2.0| \
$PLACE.2.0.*| \
$PLACE.2.1| \
$PLACE.2.1.0| \
$PLACE.2.1.0.*| \
$PLACE.2.1.1| \
$PLACE.2.1.1.*| \
$PLACE.2.1.2| \
$PLACE.2.1.2.0) RET=$PLACE.2.1.2.1 ;; # netSnmpPassInteger.1
$PLACE.2.1.2.*| \
$PLACE.2.1.3| \
$PLACE.2.1.3.0) RET=$PLACE.2.1.3.1 ;; # netSnmpPassOID.1
$PLACE.2.*| \
$PLACE.3) RET=$PLACE.3.0 ;; # netSnmpPassTimeTicks.0
$PLACE.3.*| \
$PLACE.4) RET=$PLACE.4.0 ;; # netSnmpPassIpAddress.0
$PLACE.4.*| \
$PLACE.5) RET=$PLACE.5.0 ;; # netSnmpPassCounter.0
$PLACE.5.*| \
$PLACE.6) RET=$PLACE.6.0 ;; # netSnmpPassGauge.0
*) exit 0 ;;
esac
else
#
# GET requests - check for valid instance
#
case "$REQ" in
$PLACE.1.0| \
$PLACE.2.1.2.1| \
$PLACE.2.1.3.1| \
$PLACE.3.0| \
$PLACE.4.0| \
$PLACE.5.0| \
$PLACE.6.0) RET=$REQ ;;
*) exit 0 ;;
esac
fi
#
# "Process" GET* requests - return hard-coded value
#
echo "$RET"
case "$RET" in
$PLACE.1.0) echo "string"; echo "Life, the Universe, and Everything"; exit 0 ;;
$PLACE.2.1.2.1) echo "integer"; echo "42"; exit 0 ;;
$PLACE.2.1.3.1) echo "objectid"; echo "$PLACE.99"; exit 0 ;;
$PLACE.3.0) echo "timeticks"; echo "363136200"; exit 0 ;;
$PLACE.4.0) echo "ipaddress"; echo "127.0.0.1"; exit 0 ;;
$PLACE.5.0) echo "counter"; echo "42"; exit 0 ;;
$PLACE.6.0) echo "gauge"; echo "42"; exit 0 ;;
*) echo "string"; echo "ack... $RET $REQ"; exit 0 ;; # Should not happen
esac
The MIB looks like this:
root#sama5d2-xplained:/usr/share/snmp/mibs# cat NET-SNMP-PASS-MIB.txt
NET-SNMP-PASS-MIB DEFINITIONS ::= BEGIN
--
-- Example MIB objects for "pass" and "pass-persist" extension script
--
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, TimeTicks, IpAddress,
Counter32, Gauge32, Integer32 FROM SNMPv2-SMI
SnmpAdminString FROM SNMP-FRAMEWORK-MIB
netSnmpExamples FROM NET-SNMP-EXAMPLES-MIB
;
netSnmpPassExamples MODULE-IDENTITY
LAST-UPDATED "200905280000Z"
ORGANIZATION "www.net-snmp.org"
CONTACT-INFO
"postal: Wes Hardaker
P.O. Box 382
Davis CA 95617
email: net-snmp-coders#lists.sourceforge.net"
DESCRIPTION
"Example MIB objects for pass/pass-persist extension script"
::= { netSnmpExamples 255 }
--
-- Example scalars
--
netSnmpPassString OBJECT-TYPE
SYNTAX SnmpAdminString
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example string scalar object."
DEFVAL { "Life, the Universe, and Everything" }
::= { netSnmpPassExamples 1 }
netSnmpPassTimeTicks OBJECT-TYPE
SYNTAX TimeTicks
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example timetick object."
DEFVAL { 363136200 } -- 42 days, 0:42:42.00
::= { netSnmpPassExamples 3 }
netSnmpPassIpAddress OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example IP Address object."
DEFVAL { '7f000001'H } -- 127.0.0.1
::= { netSnmpPassExamples 4 }
netSnmpPassCounter OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Example counter object.
Note that this object will always return the value '42'."
::= { netSnmpPassExamples 5 }
netSnmpPassGauge OBJECT-TYPE
SYNTAX Gauge32
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example Gauge object."
DEFVAL { 42 }
::= { netSnmpPassExamples 6 }
netSnmpPassOIDValue OBJECT IDENTIFIER
::= { netSnmpPassExamples 99 }
--
-- Example Table
--
netSnmpPassTable OBJECT-TYPE
SYNTAX SEQUENCE OF NetSnmpPassEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Example table"
::= { netSnmpPassExamples 2 }
netSnmpPassEntry OBJECT-TYPE
SYNTAX NetSnmpPassEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Conceptual row in the example table."
INDEX { netSnmpPassIndex }
::= {netSnmpPassTable 1 }
NetSnmpPassEntry ::= SEQUENCE {
netSnmpPassIndex Integer32,
netSnmpPassInteger Integer32,
netSnmpPassOID OBJECT IDENTIFIER
}
netSnmpPassIndex OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Arbitrary index into the netSnmpPassTable.
Note that there will always be one row, with index 1"
::= { netSnmpPassEntry 1 }
netSnmpPassInteger OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example Integer (table) object."
DEFVAL { 42 }
::= { netSnmpPassEntry 2 }
netSnmpPassOID OBJECT-TYPE
SYNTAX OBJECT IDENTIFIER
MAX-ACCESS read-write
STATUS current
DESCRIPTION "Example OID (table) object."
DEFVAL { netSnmpPassOIDValue }
::= { netSnmpPassEntry 3 }
END
However, when I try to do a snmpget from my host, I get the following response:
bernardo#bernardo-ThinkCentre-Edge72:~$ snmpget -v1 -c public 192.168.0.190 .1.3.6.1.4.1.2021.255.1
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: iso.3.6.1.4.1.2021.255.1
What am I missing??

Related

bash access associative array creates unbound variable [duplicate]

Using:
set -o nounset
Having an indexed array like:
myArray=( "red" "black" "blue" )
What is the shortest way to check if element 1 is set?
I sometimes use the following:
test "${#myArray[#]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist"
I would like to know if there's a preferred one.
How to deal with non-consecutive indexes?
myArray=()
myArray[12]="red"
myArray[51]="black"
myArray[129]="blue"
How to quick check that 51 is already set for example?
How to deal with associative arrays?
declare -A myArray
myArray["key1"]="red"
myArray["key2"]="black"
myArray["key3"]="blue"
How to quick check that key2 is already used for example?
To check if the element is set (applies to both indexed and associative array)
[ "${array[key]+abc}" ] && echo "exists"
Basically what ${array[key]+abc} does is
if array[key] is set, return abc
if array[key] is not set, return nothing
References:
See Parameter Expansion in Bash manual and the little note
if the colon is omitted, the operator tests only for existence [of parameter]
This answer is actually adapted from the answers for this SO question: How to tell if a string is not defined in a bash shell script?
A wrapper function:
exists(){
if [ "$2" != in ]; then
echo "Incorrect usage."
echo "Correct usage: exists {key} in {array}"
return
fi
eval '[ ${'$3'[$1]+muahaha} ]'
}
For example
if ! exists key in array; then echo "No such array element"; fi
From man bash, conditional expressions:
-v varname
True if the shell variable varname is set (has been assigned a value).
example:
declare -A foo
foo[bar]="this is bar"
foo[baz]=""
if [[ -v "foo[bar]" ]] ; then
echo "foo[bar] is set"
fi
if [[ -v "foo[baz]" ]] ; then
echo "foo[baz] is set"
fi
if [[ -v "foo[quux]" ]] ; then
echo "foo[quux] is set"
fi
This will show that both foo[bar] and foo[baz] are set (even though the latter is set to an empty value) and foo[quux] is not.
New answer
From version 4.2 of bash (and newer), there is a new -v option to built-in test command.
From version 4.3, this test could address element of arrays.
array=([12]="red" [51]="black" [129]="blue")
for i in 10 12 30 {50..52} {128..131};do
if [ -v 'array[i]' ];then
echo "Variable 'array[$i]' is defined"
else
echo "Variable 'array[$i]' not exist"
fi
done
Variable 'array[10]' not exist
Variable 'array[12]' is defined
Variable 'array[30]' not exist
Variable 'array[50]' not exist
Variable 'array[51]' is defined
Variable 'array[52]' not exist
Variable 'array[128]' not exist
Variable 'array[129]' is defined
Variable 'array[130]' not exist
Variable 'array[131]' not exist
Note: regarding ssc's comment, I've single quoted 'array[i]' in -v test, in order to satisfy shellcheck's error SC2208. This seem not really required here, because there is no glob character in array[i], anyway...
This work with associative arrays in same way:
declare -A aArray=([foo]="bar" [bar]="baz" [baz]=$'Hello world\041')
for i in alpha bar baz dummy foo test;do
if [ -v 'aArray[$i]' ];then
echo "Variable 'aArray[$i]' is defined"
else
echo "Variable 'aArray[$i]' not exist"
fi
done
Variable 'aArray[alpha]' not exist
Variable 'aArray[bar]' is defined
Variable 'aArray[baz]' is defined
Variable 'aArray[dummy]' not exist
Variable 'aArray[foo]' is defined
Variable 'aArray[test]' not exist
With a little difference:In regular arrays, variable between brackets ([i]) is integer, so dollar symbol ($) is not required, but for associative array, as key is a word, $ is required ([$i])!
Old answer for bash prior to V4.2
Unfortunately, bash give no way to make difference betwen empty and undefined variable.
But there is some ways:
$ array=()
$ array[12]="red"
$ array[51]="black"
$ array[129]="blue"
$ echo ${array[#]}
red black blue
$ echo ${!array[#]}
12 51 129
$ echo "${#array[#]}"
3
$ printf "%s\n" ${!array[#]}|grep -q ^51$ && echo 51 exist
51 exist
$ printf "%s\n" ${!array[#]}|grep -q ^52$ && echo 52 exist
(give no answer)
And for associative array, you could use the same:
$ unset array
$ declare -A array
$ array["key1"]="red"
$ array["key2"]="black"
$ array["key3"]="blue"
$ echo ${array[#]}
blue black red
$ echo ${!array[#]}
key3 key2 key1
$ echo ${#array[#]}
3
$ set | grep ^array=
array=([key3]="blue" [key2]="black" [key1]="red" )
$ printf "%s\n" ${!array[#]}|grep -q ^key2$ && echo key2 exist || echo key2 not exist
key2 exist
$ printf "%s\n" ${!array[#]}|grep -q ^key5$ && echo key5 exist || echo key5 not exist
key5 not exist
You could do the job without the need of externals tools (no printf|grep as pure bash), and why not, build checkIfExist() as a new bash function:
$ checkIfExist() {
eval 'local keys=${!'$1'[#]}';
eval "case '$2' in
${keys// /|}) return 0 ;;
* ) return 1 ;;
esac";
}
$ checkIfExist array key2 && echo exist || echo don\'t
exist
$ checkIfExist array key5 && echo exist || echo don\'t
don't
or even create a new getIfExist bash function that return the desired value and exit with false result-code if desired value not exist:
$ getIfExist() {
eval 'local keys=${!'$1'[#]}';
eval "case '$2' in
${keys// /|}) echo \${$1[$2]};return 0 ;;
* ) return 1 ;;
esac";
}
$ getIfExist array key1
red
$ echo $?
0
$ # now with an empty defined value
$ array["key4"]=""
$ getIfExist array key4
$ echo $?
0
$ getIfExist array key5
$ echo $?
1
What about a -n test and the :- operator?
For example, this script:
#!/usr/bin/env bash
set -e
set -u
declare -A sample
sample["ABC"]=2
sample["DEF"]=3
if [[ -n "${sample['ABC']:-}" ]]; then
echo "ABC is set"
fi
if [[ -n "${sample['DEF']:-}" ]]; then
echo "DEF is set"
fi
if [[ -n "${sample['GHI']:-}" ]]; then
echo "GHI is set"
fi
Prints:
ABC is set
DEF is set
tested in bash 4.3.39(1)-release
declare -A fmap
fmap['foo']="boo"
key='foo'
# should echo foo is set to 'boo'
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
key='blah'
# should echo blah is unset in fmap
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
Reiterating this from Thamme:
[[ ${array[key]+Y} ]] && echo Y || echo N
This tests if the variable/array element exists, including if it is set to a null value. This works with a wider range of bash versions than -v and doesn't appear sensitive to things like set -u. If you see a "bad array subscript" using this method please post an example.
This is the easiest way I found for scripts.
<search> is the string you want to find, ASSOC_ARRAY the name of the variable holding your associative array.
Dependign on what you want to achieve:
key exists:
if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[#]}"); then echo key is present; fi
key exists not:
if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[#]}"); then echo key not present; fi
value exists:
if grep -qe "<search>" <(echo "${ASSOC_ARRAY[#]}"); then echo value is present; fi
value exists not:
if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[#]}"); then echo value not present; fi
I wrote a function to check if a key exists in an array in Bash:
# Check if array key exists
# Usage: array_key_exists $array_name $key
# Returns: 0 = key exists, 1 = key does NOT exist
function array_key_exists() {
local _array_name="$1"
local _key="$2"
local _cmd='echo ${!'$_array_name'[#]}'
local _array_keys=($(eval $_cmd))
local _key_exists=$(echo " ${_array_keys[#]} " | grep " $_key " &>/dev/null; echo $?)
[[ "$_key_exists" = "0" ]] && return 0 || return 1
}
Example
declare -A my_array
my_array['foo']="bar"
if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then
echo "OK"
else
echo "ERROR"
fi
Tested with GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
For all time people, once and for all.
There's a "clean code" long way, and there is a shorter, more concise, bash centered way.
$1 = The index or key you are looking for.
$2 = The array / map passed in by reference.
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
for key in "${!haystack[#]}"; do
if [[ $key == $needle ]] ;
return 0
fi
done
return 1
}
A linear search can be replaced by a binary search, which would perform better with larger data sets. Simply count and sort the keys first, then do a classic binary halving of of the haystack as you get closer and closer to the answer.
Now, for the purist out there that is like "No, I want the more performant version because I may have to deal with large arrays in bash," lets look at a more bash centered solution, but one that maintains clean code and the flexibility to deal with arrays or maps.
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
[ -n ${haystack["$needle"]+found} ]
}
The line [ -n ${haystack["$needle"]+found} ]uses the ${parameter+word} form of bash variable expansion, not the ${parameter:+word} form, which attempts to test the value of a key, too, which is not the matter at hand.
Usage
local -A person=(firstname Anthony lastname Rutledge)
if hasMapKey "firstname" person; then
# Do something
fi
When not performing substring expansion, using the form described
below (e.g., ‘:-’), Bash tests for a parameter that is unset or null.
Omitting the colon results in a test only for a parameter that is
unset. Put another way, if the colon is included, the operator tests
for both parameter’s existence and that its value is not null; if the
colon is omitted, the operator tests only for existence.
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
${parameter:=word}
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional
parameters and special parameters may not be assigned to in this way.
${parameter:?word}
If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard
error and the shell, if it is not interactive, exits. Otherwise, the
value of parameter is substituted. ${parameter:+word}
If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
If $needle does not exist expand to nothing, otherwise expand to the non-zero length string, "found". This will make the -n test succeed if the $needle in fact does exist (as I say "found"), and fail otherwise.
Both in the case of arrays and hash maps I find the easiest and more straightforward solution is to use the matching operator =~.
For arrays:
myArray=("red" "black" "blue")
if [[ " ${myArray[#]} " =~ " blue " ]]; then
echo "blue exists in myArray"
else
echo "blue does not exist in myArray"
fi
NOTE: The spaces around the array guarantee the first and last element can match. The spaces around the value guarantee an exact match.
For hash maps, it's actually the same solution since printing a hash map as a string gives you a list of its values.
declare -A myMap
myMap=(
["key1"]="red"
["key2"]="black"
["key3"]="blue"
)
if [[ " ${myMap[#]} " =~ " blue " ]]; then
echo "blue exists in myMap"
else
echo "blue does not exist in myMap"
fi
But what if you would like to check whether a key exists in a hash map? In the case you can use the ! operator which gives you the list of keys in a hash map.
if [[ " ${!myMap[#]} " =~ " key3 " ]]; then
echo "key3 exists in myMap"
else
echo "key3 does not exist in myMap"
fi
I get bad array subscript error when the key I'm checking is not set. So, I wrote a function that loops over the keys:
#!/usr/bin/env bash
declare -A helpList
function get_help(){
target="$1"
for key in "${!helpList[#]}";do
if [[ "$key" == "$target" ]];then
echo "${helpList["$target"]}"
return;
fi
done
}
targetValue="$(get_help command_name)"
if [[ -z "$targetvalue" ]];then
echo "command_name is not set"
fi
It echos the value when it is found & echos nothing when not found. All the other solutions I tried gave me that error.

bash: -c: line 9: syntax error near unexpected token `fi'

I'm trying to write this script
It's read variables from csv file and make SSH connections thourgh these variables and then run an if condition inside the SSH.
#!/bin/bash
# ------------------------------------------
INPUT=Mnt.csv
OLDIFS=$IFS
IFS=','
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read rom alias port ver
do
ssh -n $alias "cd /opt/app;
echo ========================================================
find . -maxdepth 4 -type d -name '$rom' -print;
echo $port;
if [ ${ver} -eq 'v3' ]
then
cat /opt/app/v3
elif
cat /opt/app/v2
fi
;
exit"
done < $INPUT
IFS=$OLDIFS
It gives this error:
bash: -c: line 9: syntax error near unexpected token `fi'
bash: -c: line 9: ` fi'
Please can you help
Thanks
I've just corrected it like this anything work
"cd /opt/app;
echo ========================================================
find . -maxdepth 4 -type d -name '$rom' -print
echo $port
if [ ${ver} = "v3" ]
then
cat /opt/app/v3
else
cat /opt/app/v2
fi
exit"

In Bash how can I test if the array is declared if I only have its name

This question very similar to this.
In BASH, I want to check whether all the variables/arrays are properly set before I proceed.
I have a little script (check-variables) that does this successfully with ordinary variables, but not arrays.
How can I make it work for arrays too?
cat check-variables
#!/bin/bash
# This script checks to see if variables have been set and reports their value.
flag=0
for which_variable in "${#}" ; do
if [ -z "${!which_variable:-}" ]; then
if [ "${!which_variable+defined}" = defined ]; then
echo -e "$which_variable is \"\", but set "
else
if [[ -v ${!which_variable} ]]; then
echo -e "array $which_variable set"
else
flag=1
echo -e "$which_variable is not set"
fi
fi
else
echo -e "$which_variable = \"${!which_variable}\" "
fi
done
exit $flag
export scenarios=(apple banana)
export x=5
export y=8
check-variables x y scenarios
x = "5"
y = "8"
scenarios is not set
I would like the output's last line to say:
scenarios = (apple banana)

Performing IF Statement in awk

I have an array of users and I need to see if the owner of a file (logfile.log) exists within the array. Using awk I am able to pull the owner ($3) but when I use try to see if $3 is in user I get a syntax error at the beginning of my if statement. My limited understanding is that awk is not liking the syntax.
user=('michael' 'mark' 'luke' 'john' 'phil' 'sam' 'kevin');
ls -ldL logfile.log 2>/dev/null |
/bin/awk '{
Result = $NF ":\tPermissions=" $1;
if ([[ "${user[*]}" =~ (^|[^[:alpha:]])$3([^[:alpha:]]|$) ]]) {
Result = Result "\tOwner=SUPPORT";
}
else {
Result = Result "\tOwner=" $3;
}
print Result;
}'
Don't parse ls (http://mywiki.wooledge.org/ParsingLs). Use stat to get the owner (check your stat man page, there are different implementations of different OS's)
# give your arrays a plural variable name
users=('michael' 'mark' 'luke' 'john' 'phil' 'sam' 'kevin')
owner=$(stat -c '%U' logfile.log)
if [[ " ${users[*]} " == *" $owner "* ]]; then # spaces are deliberate
echo logfile.log has a valid owner: $owner
else
echo logfile.log is not owned by a valid user: $owner
fi
The other approach is to iterate over the array and look for an exact match:
valid=false
for user in "${users[#]}"; do
if [[ $user == $owner ]]; then
valid=true
break
fi
done
if $valid; then
echo file has a valid owner
fi
The main problem in your code is that you expect awk to understand bash syntax. It doesn't.

Search array return index in bash

Just pesuocode but this is essentially what I would like to do.
Array=("1" "Linux" "Test system"
"2" "Windows" "Workstation"
"3" "Windows" "Workstation")
echo "number " ${array[search "$1"]} "is a" ${array[search "$1" +1]} ${array[search "$1" +2])}
Is this possible with bash? I could only find info on search and replace. I didn't see anything That would return and index.
Something like that should work:
search() {
local i=1;
for str in "${array[#]}"; do
if [ "$str" = "$1" ]; then
echo $i
return
else
((i++))
fi
done
echo "-1"
}
While looping over the array to find the index is certainly possible, this alternative solution with an associative array is more practical:
array=([1,os]="Linux" [1,type]="Test System"
[2,os]="Windows" [2,type]="Work Station"
[3,os]="Windows" [3,type]="Work Station")
echo "number $1 is a ${array[$1,os]} ${array[$1,type]}"
You could modify this example from this link to return an index without much trouble:
# Check if a value exists in an array
# #param $1 mixed Needle
# #param $2 array Haystack
# #return Success (0) if value exists, Failure (1) otherwise
# Usage: in_array "$needle" "${haystack[#]}"
# See: http://fvue.nl/wiki/Bash:_Check_if_array_element_exists
in_array() {
local hay needle=$1
shift
for hay; do
[[ $hay == $needle ]] && return 0
done
return 1
}

Resources