Reputation: 431
I have a function:
function checkConn()
{
RET=0
echo "in function: ${2}"
echo
for i in `cat ${1}`
do
for p in ${2}
do
if nc -dzw 2 ${i} ${p} 2>&1 >/dev/null
and so on.
In the "main" body of the script, I have the following:
PORTS='22 161 162 1521'
checkConn ${FILE} ${PORTS}
FILE is the name of a file which contains a list of IPs.
When I pass PORTS to the function, only the 1st item gets passed. I also tried it with double-quotes.
I put that "echo" statement to confirm. It only shows the first item in PORTS, which is 22.
How can I pass all the ports to this function, and then loop through each one?
Upvotes: 0
Views: 65
Reputation: 85550
Multiple syntax violations and outdated constructs, you probably need something like,
function checkConn() {
# define variables as local unless you are using it beyond the scope
# of the function and always lower-case variable names
local ret=0
printf "%s\n" "$2"
# Splitting the string into an array so that it can be accessed
# element wise inside the loop. The -a option in read stores the
# elements read to the array
read -ra portList <<<"$2"
# Input-redirection of reading the file represented by argument $1
# representing the file name. The files are read one at a time
while IFS= read -r line; do
# Array values iterated in a for-loop; do the action
# for each value in the port number
for port in "${portList[@]}"; do
if nc -dzw 2 "$line" "$port" 2>&1 >/dev/null; then
printf "%s %s\n" "$line" "$port"
# Your rest of the code
fi
done
done < "$1"
}
and call the function as
ports='22 161 162 1521'
filename="file"
checkConn "$filename" "$PORTS"
Upvotes: 1
Reputation: 295288
Best practice is to pass the list of ports as individual arguments, each with their own argv entry -- like so:
checkConn() {
file=$1; shift ## read filename from $1, then remove it from the argument list
while IFS= read -r address; do
for port; do ## we shifted off the filename so this only iterates over ports
if nc -dzw 2 "$address" "$port" </dev/null >/dev/null 2>&1; then
echo "$address $port OPEN"
else
echo "$address $port CLOSED"
fi
done
done <"$file"
}
file=addrs.txt
ports=( 22 161 162 1521 )
checkConn "$file" "${ports[@]}"
Notes:
function
keyword is not actually required for use to define a function; it makes your code incompatible with POSIX sh, but provides no benefit over the portable syntax. Avoid it.while IFS= read -r
idiom is described in detail in BashFAQ #1. Also see Don't Read Lines With For.ports=( ... )
and "${ports[@]}"
syntax, are described in the BashGuide.Upvotes: 2