LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-15-2012, 09:34 PM   #1
Ziddy
LQ Newbie
 
Registered: Jun 2012
Location: Ontario
Distribution: BackTrack
Posts: 15

Rep: Reputation: Disabled
A little bash problem


Hey, I need some help with bash. I'm sure I'm gonna explain this in the most confusing way possible, so hopefully someone understands. I have two variables. $NAMES and $HOSTS. I'm using a for-loop. Each loop, it goes to the next in the $NAMES list, but I also want it to do the same for $HOSTS, without executing the code in the loop twice, or jumping to the very end of the list of the 2nd variable. (Which is what happens when I use two for-loops). I've tried...
for myName in $NAMES && for myHost in $HOSTS do
and a bunch of other combinations.. Brackets, pipes, semi-colons...
I want $NAMES and $HOSTS to stay in the same position as each other.
If $NAMES is on the 2nd in the list, so should $HOSTS.

Thanks for reading, and I'm sorry if I've confused you!
It seems like it should be so simple, but it's causing me quite a bit of problems.

Last edited by Ziddy; 06-16-2012 at 12:41 AM. Reason: Solved
 
Old 06-15-2012, 09:42 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
You say you want to go to different items in these two variables----what separates the items?---eg commas, colons, line feeds...etc.

It seems to me that you might be better off with arrays rather than a bunch of fields in variable name. With arrays, you just run a counter in your main loop, then use $counter to index into the arrays.
 
Old 06-15-2012, 09:52 PM   #3
Ziddy
LQ Newbie
 
Registered: Jun 2012
Location: Ontario
Distribution: BackTrack
Posts: 15

Original Poster
Rep: Reputation: Disabled
Well the for-loop goes to the next one in the variable, correct? It works fine with just one, but with two it doesn't.
Hrm. Lemme show you an example.

$NAMES="hi blah blarg"
$HOSTS="ip1 ip2 ip3"

for myName in $NAMES
do
for myHost in $HOSTS
do
if [ ${count:-0} -eq 0 ] || [ -z "$count" ]; then
echo -e "Host "$myName" ($myHost) is\t \033[31mOFFLINE\033[0m $(date)"
else
echo -e "Host "$myName" ($myHost) is\t \033[32mONLINE!\033[0m $(date)"
fi
done
done

This works fine, except $myName skips to the very last one in the list, when I want it to stay with $myHost.

edit: I'm sure I'm over-thinking this :\
 
Old 06-15-2012, 10:29 PM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Quote:
Well the for-loop goes to the next one in the variable, correct?
It does?---have your tried it?

Regardless, you have 2 nested loops---for each pass thru the outer loop, you'll go thru all the iterations of the inner loop. I don't think that's what you had in mind...
 
Old 06-15-2012, 10:33 PM   #5
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
You are right--I was not thinking
here's the test:
Code:
[mherring@herring-lap play]$ var="one two three four"
[mherring@herring-lap play]$ echo $var
one two three four
[mherring@herring-lap play]$ for item in $var; do echo $item; done
one
two
three
four
 
Old 06-15-2012, 10:54 PM   #6
Ziddy
LQ Newbie
 
Registered: Jun 2012
Location: Ontario
Distribution: BackTrack
Posts: 15

Original Poster
Rep: Reputation: Disabled
Let me provide two examples: One without the $NAMES, one with, including the code.

Without (Output, followed by code)

Host (121.121.121.121) is OFFLINE Fri Jun 15 23:44:10 EDT 2012
Host (222.222.222.222) is ONLINE! Fri Jun 15 23:44:10 EDT 2012
Host (111.111.111.111) is OFFLINE Fri Jun 15 23:44:20 EDT 2012

#HOSTS="121.121.121.121 222.222.222.222 111.111.111.111"

for myHost in $HOSTS
do
count=$(ping -c $COUNT $myHost | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')
if [ ${count:-0} -eq 0 ] || [ -z "$count" ]; then
echo -e "Host ($myHost) is\t \033[31mOFFLINE\033[0m $(date)"
else
echo -e "Host ($myHost) is\t \033[32mONLINE!\033[0m $(date)"
fi
done


-----------------------------
With (followed by code)

$HOSTS="121.121.121.121 222.222.222.222 111.111.111.111"
$NAMES="AKILL RANDOM FILLER BUTTSECKS"

count=$(ping -c $COUNT $myHost | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')

#Check to see if ping was successful and display. With CoLoRzZz!
if [ ${count:-0} -eq 0 ] || [ -z "$count" ]; then
echo -e "Host $myName ($myHost) is\t \033[31mOFFLINE\033[0m $(date)"
else
echo -e "Host $myName ($myHost) is\t \033[32mONLINE!\033[0m $(date)"
fi
done
done

Host AKILL (121.121.121.121) is OFFLINE Fri Jun 15 23:51:39 EDT 2012
Host RANDOM (121.121.121.121) is OFFLINE Fri Jun 15 23:51:49 EDT 2012
Host FILLER (121.121.121.121) is OFFLINE Fri Jun 15 23:51:59 EDT 2012
Host BUTTSECKS (121.121.121.121) is OFFLINE Fri Jun 15 23:52:09 EDT 2012
Host AKILL (222.222.222.222) is ONLINE! Fri Jun 15 23:52:09 EDT 2012
Host RANDOM (222.222.222.222) is ONLINE! Fri Jun 15 23:52:09 EDT 2012
Host FILLER (222.222.222.222) is ONLINE! Fri Jun 15 23:52:10 EDT 2012
Host BUTTSECKS (222.222.222.222) is ONLINE! Fri Jun 15 23:52:10 EDT 2012
Host AKILL (111.111.111.111) is OFFLINE Fri Jun 15 23:52:20 EDT 2012
Host RANDOM (111.111.111.111) is OFFLINE Fri Jun 15 23:52:30 EDT 2012

As you can see, the names dont stay in sync with the hosts as they should.
I think you're correct about using arrays.
Hrm..
 
Old 06-16-2012, 12:23 AM   #7
Ziddy
LQ Newbie
 
Registered: Jun 2012
Location: Ontario
Distribution: BackTrack
Posts: 15

Original Poster
Rep: Reputation: Disabled
Alright, I figured it out. *flicks sweat*
Sorta glad I didn't get a direct answer, was able to figure it out by trail and error.
I'm sure it isn't the best way, but it works.

ii=0
for i in "${HOSTS[@]}"
do
count=$(ping -c $COUNT $i | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')



if [ ${count:-0} -eq 0 ] || [ -z "$count" ]; then
echo -e "Host ${NAMES[$ii]} ($i) is\t \033[31mOFFLINE\033[0m $(date)"
else
echo -e "Host ${NAMES[$ii]} ($i) is\t \033[32mONLINE!\033[0m $(date)"
fi


if [ "$ii" -eq ${#HOSTS[*]} ]; then
$ii=0
else
let "++ii"
fi
 
Old 06-16-2012, 09:22 AM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
The best way to check if systems are online is using nmap:
Code:
~$ HOSTS=(192.168.2.1 192.168.2.2)
~$ nmap -v -sn -oG - "${HOSTS[@]}" | grep -v '^#'
Host: 192.168.2.1 (mymodem)	Status: Up
Host: 192.168.2.2 ()	Status: Down
The -sn option says to only do a ping scan, but nmap has a lot more ways to check a host. Note that a system can be online but ignore pings, so a test with ping will think it is offline.

Adding names and formatting:
Code:
#!/bin/bash

NORMAL=$(tput setaf 0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)

HOSTS=(192.168.2.1 192.168.2.2)
declare -A NAMES
NAMES[192.168.2.1]=router
NAMES[192.168.2.2]=non-existent-host

while read _ ip _ _ status ; do
    echo -en "Host ${NAMES[$ip]} ($ip) is\t "
    if [ "$status" = Down ] ; then
        echo -n "${RED}OFFLINE"
    else
        echo -n "${GREEN}ONLINE!"
    fi
    echo "${NORMAL} $(date)"
done < <(nmap -v -sn -oG - "${HOSTS[@]}" | grep -v '^#')
Code:
~/tmp$ ./scan.bash
Host router (192.168.2.1) is	 ONLINE! Sat Jun 16 10:05:05 EDT 2012
Host non-existent-host (192.168.2.2) is	 OFFLINE Sat Jun 16 10:05:05 EDT 2012
PS please use [code][/code] tags when posting code.
 
Old 06-16-2012, 09:34 AM   #9
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by Ziddy View Post
Hey, I need some help with bash. I'm sure I'm gonna explain this in the most confusing way possible, so hopefully someone understands. I have two variables. $NAMES and $HOSTS. I'm using a for-loop. Each loop, it goes to the next in the $NAMES list, but I also want it to do the same for $HOSTS, without executing the code in the loop twice, or jumping to the very end of the list of the 2nd variable. (Which is what happens when I use two for-loops). I've tried...
for myName in $NAMES && for myHost in $HOSTS do
and a bunch of other combinations.. Brackets, pipes, semi-colons...
I want $NAMES and $HOSTS to stay in the same position as each other.
If $NAMES is on the 2nd in the list, so should $HOSTS.

Thanks for reading, and I'm sorry if I've confused you!
It seems like it should be so simple, but it's causing me quite a bit of problems.
Code:
echo $HOSTS | awk '{print $i}'
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash problem : -bash: [: /bin/bash: unary operator expected J.A.X Linux - Software 1 09-22-2011 05:52 AM
Bash BC problem mcfc1900 Programming 4 04-05-2011 03:57 PM
[SOLVED] bash : getopts problem in bash script. angel115 Programming 2 03-02-2009 10:53 AM
Reading a bash variable in bash scripting problem freeindy Programming 3 11-27-2008 02:29 AM
bash problem cL4YmAN Linux - Newbie 1 06-07-2004 01:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration