running a bash command with a timeout

  • Follow


Is there a nice way to run a command with a timeout around it? 

For example sometimes I query ~100 servers about their status using a 
command like so:

for i in $(seq 1 99); do ipmitool 172.16.0.${i} status; echo $i ; done

But let's say one server (say, 172.16.0.4) is hung or unresponsive. Then 
the loop never goes beyong this to 172.16.0.5 etc. Ideally, I'd like the 
loop to wait for, say, 10 secs. and if no response then go to the next 
index in the loop. 

Any nice way to do this? Ideally on the bash command line. But I am also 
open to other ideas.

Of course, had ipmitool an option "timeout" this problem would have been 
better addressed. But the way things stand if a server is unresponsive then 
ipmitool just waits infinitely. 


-- 
Rahul
0
Reply Rahul 7/9/2010 10:54:49 PM

On Fri, 9 Jul 2010 22:54:49 +0000 (UTC), Rahul wrote:
> Is there a nice way to run a command with a timeout around it? 
>
> For example sometimes I query ~100 servers about their status using a 

Personally, I use ping with a -w switch in my scripts. man page snippet.

       -w deadline
              Specify a timeout, in seconds, before ping exits  regardless  of
              how  many  packets have been sent or received. In this case ping
              does not stop after count packet are sent, it waits  either  for
              deadline  expire  or until count probes are answered or for some
              error notification from network.
0
Reply Bit 7/9/2010 11:00:52 PM


Bit Twister <BitTwister@mouse-potato.com> wrote in 
news:slrni3fah4.j9q.BitTwister@wb.home.test:

>> For example sometimes I query ~100 servers about their status using a 
> 
> Personally, I use ping with a -w switch in my scripts. man page snippet.
> 
>        -w deadline
> 

True. Ping works. But there's other stuff I monitor with IPMI as well. e.g. 
sensor temperatures, voltages etc.

-- 
Rahul
0
Reply Rahul 7/9/2010 11:17:51 PM

On Fri, 9 Jul 2010 22:54:49 +0000 (UTC)
Rahul <nospam@nospam.invalid> wrote:

> Is there a nice way to run a command with a timeout around it? 
> 
> For example sometimes I query ~100 servers about their status using a 
> command like so:
> 
> for i in $(seq 1 99); do ipmitool 172.16.0.${i} status; echo $i ; done
> 
> But let's say one server (say, 172.16.0.4) is hung or unresponsive.
> Then the loop never goes beyong this to 172.16.0.5 etc. Ideally, I'd
> like the loop to wait for, say, 10 secs. and if no response then go
> to the next index in the loop. 
> 
> Any nice way to do this? Ideally on the bash command line. But I am
> also open to other ideas.

Some may say this suggestion is over the top, but I'd write
a simple "c program" to launch multiple threads, each one
responsible for each "machine ping", then offer different
methods of communicating the results.  Ask me how I know :)

I did this years ago for the same reason ... I had it send
me a text message for any machine(s) not responding.

-- 
The average woman would rather have beauty than brains, because the
average man can see better than he can think.
<<< Remove YOURSHOES to email me >>>

0
Reply mjt 7/9/2010 11:28:29 PM

On 2010-07-10 01:17, Rahul wrote:
>>  use ping with a -w switch
>>
> True. Ping works. But there's other stuff I monitor with IPMI as well.

Then send one ping with the deadline, and if it succeeds continue
with ipmitool:

for i in $(seq 1 99)
do
ping -c 1 -w 10 172.16.0.${i} >/dev/null 2>&1 \
&& ipmitool 172.16.0.${i} status
echo $i
done

-- 
mrg

0
Reply marrgol 7/10/2010 12:57:40 AM

On 2010-07-09, mjt <myswtestYOURSHOES@gmail.com> wrote:
>
> Some may say this suggestion is over the top, but I'd write
> a simple "c program" to launch multiple threads, each one
> responsible for each "machine ping", then offer different
> methods of communicating the results.  Ask me how I know :)
>
> I did this years ago for the same reason ... I had it send
> me a text message for any machine(s) not responding.

It's not over the top, it's been done.  I use nagios, but there are many
other programs that do similar tasks.  I don't know what sort of IPMI
support nagios has, but a plugin can be written in any language fairly
easily if you know what the various cases are (i.e., when things are OK,
when you want to send a warning message, when you want to send a
critical alert).

--keith

-- 
kkeller-usenet@wombat.san-francisco.ca.us
(try just my userid to email me)
AOLSFAQ=http://www.therockgarden.ca/aolsfaq.txt
see X- headers for PGP signature information

0
Reply Keith 7/10/2010 3:39:14 AM

marrgol <marspamrgol@gspammail.com> wrote in news:4c37c584$0$17097$65785112
@news.neostrada.pl:

> Then send one ping with the deadline, and if it succeeds continue
> with ipmitool:
> 
> 

Ah! why didn't I think of this!  :) Thanks! That works well. 

-- 
Rahul
0
Reply Rahul 7/10/2010 3:31:45 PM

Keith Keller <kkeller-usenet@wombat.san-francisco.ca.us> wrote in 
news:2k6lg7xcct.ln2@goaway.wombat.san-francisco.ca.us:

> It's not over the top, it's been done.  I use nagios, but there are many
> other programs that do similar tasks.  I don't know what sort of IPMI
> support nagios has, but a plugin can be written in any language fairly
> easily if you know what the various cases are (i.e., when things are OK,
> when you want to send a warning message, when you want to send a
> critical alert).
> 

Thanks for those options.I'm already running nagios so I could definately 
do this from within. I was just wonderin if there was someting simple like:

$$timeout 10 foocommand

Where foocommand would run but if it exceeded 10 seconds then it would be 
killed. Maybe there is a way to write  a C wrapper that does this? i'll 
give it a shot but wanted to check if there already exists any utility like 
thhis one before reinventing the wheel. 

e.g. for issuing commands on multiple nodes I often use pssh. This does 
come with builtin timeouts.

pssh -h hostfile -t timeout foocommand

 An idea is to maybe invoke pssh on the current node itself and see if it 
works.

-- 
Rahul
0
Reply Rahul 7/10/2010 3:35:45 PM

In article <Xns9DB16BC8F9E706650A1FC0D7811DDBC81@81.169.183.62>,
Rahul  <nospam@invalid.invalid> wrote:
>Keith Keller <kkeller-usenet@wombat.san-francisco.ca.us> wrote in 
>news:2k6lg7xcct.ln2@goaway.wombat.san-francisco.ca.us:
>
>> It's not over the top, it's been done.  I use nagios, but there are many
>> other programs that do similar tasks.  I don't know what sort of IPMI
>> support nagios has, but a plugin can be written in any language fairly
>> easily if you know what the various cases are (i.e., when things are OK,
>> when you want to send a warning message, when you want to send a
>> critical alert).
>> 
>
>Thanks for those options.I'm already running nagios so I could definately 
>do this from within. I was just wonderin if there was someting simple like:
>
>$$timeout 10 foocommand

I've been using this for decades.  Works like a charm!

--- Cut Here ---
#!/usr/bin/expect --
# Usage: maxtime <maxsecs> <cmd> [<arg(s)>]
set echo ""
if {[lindex $argv 0] == "-q"} {
    set echo "-noecho"
    set argv [lrange $argv 1 end]
    }
set timeout [lindex $argv 0]
if [catch {eval spawn $echo [lrange $argv 1 end]}] {
    puts "Usage: maxtime \[-q] <timeINsecs> <cmd> \[<arg(s)>]"
    exit -1
    }
if [catch {set exitval $env(MAXTIME_exitval)}] { set exitval -1 }
expect timeout { puts stderr "[lrange $argv 1 1]: Timeout" ; exit $exitval }
exit [lrange [wait] 3 3]
--- Cut Here ---

Now, note that there is one problem with this (not relevant to your use
case, but it *has* been a problem for me).  That is, if the program you
are controlling goes into a device wait (the really bad case - the case
where the program can't be killed with the ubiquitous "kill -9"), then
the maxtime program will stall as well.  This turns out to be a side
effect of adding support for catching the exit status of the controlled
command - i.e., of using [wait].  If you remove the [wait], then it will
work even in the "bad case".  What I'd really like to do is to just
[wait] a little time - say a few seconds - then exit.  I think it is
easy enough to do - I just haven't gotten around to it.

-- 
> No, I haven't, that's why I'm asking questions. If you won't help me,
> why don't you just go find your lost manhood elsewhere.

CLC in a nutshell.

0
Reply gazelle 7/10/2010 5:42:58 PM

gazelle@shell.xmission.com (Kenny McCormack) wrote in news:i1abf2$mbd$3
@news.xmission.com:

> Now, note that there is one problem with this (not relevant to your use
> case, but it *has* been a problem for me).  That is, if the program you
> are controlling goes into a device wait (the really bad case - the case
> where the program can't be killed with the ubiquitous "kill -9"), then
> the maxtime program will stall as well.  This turns out to be a side
> effect of adding support for catching the exit status of the controlled
> command - i.e., of using [wait].  If you remove the [wait], then it will
> work even in the "bad case".  What I'd really like to do is to just
> [wait] a little time - say a few seconds - then exit.  I think it is
> easy enough to do - I just haven't gotten around to it.
> 

Thanks very much! This works like a charm. That's exactly what I wanted to 
achieve.

-- 
Rahul
0
Reply Rahul 7/10/2010 9:10:23 PM

On Fri, 09 Jul 2010 23:00:52 +0000, Bit Twister wrote:

> On Fri, 9 Jul 2010 22:54:49 +0000 (UTC), Rahul wrote:
>> Is there a nice way to run a command with a timeout around it?
>>
>> For example sometimes I query ~100 servers about their status using a
> 
> Personally, I use ping with a -w switch in my scripts. man page snippet.
> 
>        -w deadline
>               Specify a timeout, in seconds, before ping exits 
>               regardless  of how  many  packets have been sent or
>               received. In this case ping does not stop after count
>               packet are sent, it waits  either  for deadline  expire 
>               or until count probes are answered or for some error
>               notification from network.

Just wondering, how did this happen?

Eric



-- 
Sacrifice is only a test.
0
Reply Eric 7/14/2010 2:55:52 AM

In article <i1j8vo$usb$1@speranza.aioe.org>,
Eric Lee  <openlinuxsource@gmail.com> wrote:
>On Fri, 09 Jul 2010 23:00:52 +0000, Bit Twister wrote:
>
>> On Fri, 9 Jul 2010 22:54:49 +0000 (UTC), Rahul wrote:
>>> Is there a nice way to run a command with a timeout around it?
>>>
>>> For example sometimes I query ~100 servers about their status using a
>> 
>> Personally, I use ping with a -w switch in my scripts. man page snippet.
>> 
>>        -w deadline
>>               Specify a timeout, in seconds, before ping exits 
>>               regardless  of how  many  packets have been sent or
>>               received. In this case ping does not stop after count
>>               packet are sent, it waits  either  for deadline  expire 
>>               or until count probes are answered or for some error
>>               notification from network.
>
>Just wondering, how did this happen?

How did *what* happen?

-- 
> No, I haven't, that's why I'm asking questions. If you won't help me,
> why don't you just go find your lost manhood elsewhere.

CLC in a nutshell.

0
Reply gazelle 7/14/2010 2:14:10 PM

How about this

DELAY=10

PotentiallyLongCommand & 
PID=$!
(sleep $DELAY ; kill $PID) &
wait $PID

I just wrote a shell function:

ExecuteWithTimeout() {
    local TIMEOUT=$1; shift
    $@ & 
    local PID=$!
    (sleep 10; kill -9 $PID) & 
    wait $PID
}

to use it type: 

ExecuteWithTimeout 10 ipmitool blah blah bla

would kill ipmitool in 10 seconds.
1
Reply Ignoramus2398 7/14/2010 3:43:15 PM

12 Replies
2398 Views

(page loaded in 0.178 seconds)

Similiar Articles:


















7/20/2012 4:58:40 PM


Reply: