After much searching, I've decided to resort to the tried and true LQ Forums. Here's what I'm trying to accomplish:

I need to ping several nodes one at a time with a single ping, over and over. When it reaches the bottom of the list, I want it to go back to the top and do it over again, infinitely. Here's what I tried so far:

This appears to work, however, it created a bit of a problem where the CPU was spiking after a while. I investigated and found out that the script didn't work the way I thought it would, as it basically created multiple instances of the script process over and over again without killing the previous one as I assumed it would. So, I ended up slamming the server. I know it's because of the nesting of the while loops, combined with the "while true" statement, but I can't really think of another way to do it. Anyone got any ideas?

Thanks in advance,

wolverene13

towheedm

11-14-2012 08:53 PM

I busted my brains trying to figure out where your script calls itself. Finally, decided to run it with one modification. The variable $? returns the exit status of the last command, or according to BASH's textinfo pages:

Quote:

? Expands to the exit status of the most recently executed fore‐
ground pipeline.

As it is in your script it will return the exit status of the read NODE command. Moving it to after the ping command and running your script did not create (according to top) any additional processes.

You can also do away with the if-then statement by using the && and || commands. Also redirect both stderr and stdout to /dev/null.

I busted my brains trying to figure out where your script calls itself. Finally, decided to run it with one modification. The variable $? returns the exit status of the last command, or according to BASH's textinfo pages:

As it is in your script it will return the exit status of the read NODE command. Moving it to after the ping command and running your script did not create (according to top) any additional processes.

You can also do away with the if-then statement by using the && and || commands. Also redirect both stderr and stdout to /dev/null.

Awesome! Both solutions worked perfectly! Thanks! I'm confused though - when using the || operator, how does it know whether to echo failed or alive?

towheedm

11-14-2012 09:32 PM

From BASHs info pages:

Quote:

Lists
A list is a sequence of one or more pipelines separated by one of the
operators ;, &, &&, or ⎪⎪, and optionally terminated by one of ;, &, or
<newline>.

Of these list operators, && and ⎪⎪ have equal precedence, followed by ;
and &, which have equal precedence.

A sequence of one or more newlines may appear in a list instead of a
semicolon to delimit commands.

If a command is terminated by the control operator &, the shell exe‐
cutes the command in the background in a subshell. The shell does not
wait for the command to finish, and the return status is 0. Commands
separated by a ; are executed sequentially; the shell waits for each
command to terminate in turn. The return status is the exit status of
the last command executed.

AND and OR lists are sequences of one of more pipelines separated by
the && and ⎪⎪ control operators, respectively. AND and OR lists are
executed with left associativity. An AND list has the form

command1 && command2

command2 is executed if, and only if, command1 returns an exit status
of zero.

An OR list has the form

command1 ⎪⎪ command2

command2 is executed if and only if command1 returns a non-zero exit
status. The return status of AND and OR lists is the exit status of
the last command executed in the list.

So basically:

Code:

command1 && command2 || command3

If command1 returns an exit status of 0, command2 gets executed and the lists ends.
It becomes:

Code:

command1 && command2

If command1 returns an exit status other than 0, then command2 does not get executed. Instead command3 gets executed:

Code:

command1 || command3

So basically:

Code:

command1 && command2 || command3

says: If command1 succeeds then exucute command2 else execute command3, which is why it's the same as: