alarm() functionality from the shell
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > alarm() functionality from the shell




Pages (2): [1] 2 »   Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    alarm() functionality from the shell  
Martin Carpenter


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 12:48 PM


Problem: I have a command that runs from the shell, from which I need to
obtain stdout and stderr, and retain the return code ($?). Sometimes, this
command will hang indefinitely, and therefore I'd like to be able to kill it
after a specified time period. (Further detail at the foot of this post).

Given that I need to keep the return code, I don't believe that I can put
the command into the background or use coprocesses (ksh/bash), unless I do
some hackery by writing $? to a temporary file or similar. Ideally, what I'd
like would be a command-line "timeout" utility:

out=`to 180 foo 2>&1`
rc=$?

for a timeout of three minutes. Is there such a thing?

I found some old posts from David Korn, applicable to ksh93, which is almost
what I need, but I only have 88i (Solaris 8):


[url]https://mailman.research.att.com/pipermail/uwin-developers/2003q2/000641.html[/url
]

I also found Michael Wang's "submit":

http://www.unixlabplus.com/unix-prog/submit/submit

which seems a little excessive for my needs (I don't like all of the writing
to temporary files - I'd really like something that I can drop in).

I've written a 200 line C program, a slightly anaemic version of Wang's
"submit", to do what I want, in which I fork(), execvp(), alarm(), waitpid()
and kill() as necessary. This seems fine... but is there a better way?

All suggestions to port JCL/JES will be roundly ignored ;-)





FWIW, what I'm really doing here: running Solaris' smpatch(1M) via ssh.
E.g.,

patches=`ssh -i$idfile root@$machine smpatch analyze 2>&1`

Sometimes, this will hang... indefinitely... I've sought a timeout feature
in ssh, but only found the KeepAlive options.








[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
alexs


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 12:48 PM


Martin Carpenter wrote:
> Problem: I have a command that runs from the shell, from which I need to
> obtain stdout and stderr, and retain the return code ($?). Sometimes, this
> command will hang indefinitely, and therefore I'd like to be able to kill 
it
> after a specified time period. (Further detail at the foot of this post).
>
> Given that I need to keep the return code, I don't believe that I can put
> the command into the background or use coprocesses (ksh/bash), unless I do
> some hackery by writing $? to a temporary file or similar. Ideally, what I
'd
> like would be a command-line "timeout" utility:
>
>    out=`to 180 foo 2>&1`
>    rc=$?
>
> for a timeout of three minutes. Is there such a thing?
>
> I found some old posts from David Korn, applicable to ksh93, which is almo
st
> what I need, but I only have 88i (Solaris 8):
>
>
> [url]https://mailman.research.att.com/pipermail/uwin-developers/2003q2/000641.html[/u
rl]
>
> I also found Michael Wang's "submit":
>
>   http://www.unixlabplus.com/unix-prog/submit/submit
>
> which seems a little excessive for my needs (I don't like all of the writi
ng
> to temporary files - I'd really like something that I can drop in).
>
> I've written a 200 line C program, a slightly anaemic version of Wang's
> "submit", to do what I want, in which I fork(), execvp(), alarm(), waitpid
()
> and kill() as necessary. This seems fine... but is there a better way?
>
> All suggestions to port JCL/JES will be roundly ignored ;-)
>
>
>
>
>
> FWIW, what I'm really doing here: running Solaris' smpatch(1M) via ssh.
> E.g.,
>
>     patches=`ssh -i$idfile root@$machine smpatch analyze 2>&1`
>
> Sometimes, this will hang... indefinitely... I've sought a timeout feature
> in ssh, but only found the KeepAlive options.

Hi
Sorry if I've misunderstood your question, but if you want to
automatically kill the process after 3 minutes you could try something
like:

prog > out 2> err & ( sleep 180; kill $! )

Im guessing $? will no longer work in that scenario though, so you need
to assign it somehow (but im not sure how to do that!)






[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
Martin Carpenter


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 11:01 PM


"alexs" <spam@alexs.org> wrote:

> Sorry if I've misunderstood your question,

No, I think you got it.


> you could try something like:
>
> prog > out 2> err & ( sleep 180; kill $! )
>
> Im guessing $? will no longer work in that scenario
> though, so you need to assign it somewho (but im not
> sure how to do that!)

Yes, that's exactly my problem :-/ As I said in my intro, I don't think it's
possible to capture $? if you start the process in the background [witho
ut
resorting to zany hackery].








[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
alexs


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 11:01 PM

> Yes, that's exactly my problem :-/ As I said in my intro,
>I don't think it's possible to capture $? if you start the process
>in the background [without resorting to zany hackery].

I think zany hackery is order of the day:

http://groups.google.com/group/comp...eb442a548c7a0b3

Altho that looks a little excessive. Maybe something like:

( prog > out 2> err; echo $? > rc ) & ( sleep 2; kill $! )

If rc exists, the prog terminated normally and contains the code. else
it was killed.






[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
Chuck Dillon


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 11:01 PM

Martin Carpenter wrote:

>
> I found some old posts from David Korn, applicable to ksh93, which is almo
st
> what I need, but I only have 88i (Solaris 8):

Use dtksh on Solaris 8 to get ksh93 compatibility...

-- ced


--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.





[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
Heiner Steven


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 11:01 PM

Martin Carpenter wrote:
> Problem: I have a command that runs from the shell, from which I need to
> obtain stdout and stderr, and retain the return code ($?). Sometimes, this
> command will hang indefinitely, and therefore I'd like to be able to kill 
it
> after a specified time period. (Further detail at the foot of this post).

http://www.shelldorado.com/scripts/cmds/timeout

Heiner
--
___ _
/ __| |_ _____ _____ _ _     Heiner STEVEN <heiner.steven@nexgo.de>
\__ \  _/ -_) V / -_) ' \    Shell Script Programmers: visit
|___/\__\___|\_/\___|_||_|   http://www.shelldorado.com/





[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
William Ahern


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-16-05 11:01 PM

Martin Carpenter <mcarpenter@free.fr> wrote:
> Problem: I have a command that runs from the shell, from which I need to
> obtain stdout and stderr, and retain the return code ($?). Sometimes, this
> command will hang indefinitely, and therefore I'd like to be able to kill 
it
> after a specified time period. (Further detail at the foot of this post).

> Given that I need to keep the return code, I don't believe that I can put
> the command into the background or use coprocesses (ksh/bash), unless I do
> some hackery by writing $? to a temporary file or similar. Ideally, what I
'd
> like would be a command-line "timeout" utility:
>
>    out=`to 180 foo 2>&1`
>    rc=$?
>
> for a timeout of three minutes. Is there such a thing?
>
> I found some old posts from David Korn, applicable to ksh93, which is almo
st
> what I need, but I only have 88i (Solaris 8):

Personally I don't think using temporary files is hackery. You're simply
doing IPC, something the Unix filesystem was intended to be used for. I use
the following functions in several regression test scripts, and I'm not
afraid to create temporary named pipes or files to store return codes. I'm
using bash, though. I don't know how portable the waitpid implementation is.

In the past I've also written long pipelines where I saved several error
codes and stderr output to intermediate temporary files and never felt
dirty.


#
# Usage: tempnam [<pretty name>]
#
# TMPFILE=$(tempnam "example")
#
function tempnam {
if [ -z "$TMPDIR" ]; then
TMPDIR=/tmp
fi

echo ${TMPDIR}/${1}$(hexdump -n8 -e '"%02x"' /dev/urandom)

return $?
} # tempnam


#
# Usage: waitpid <pid> <timeout>
#
# Return value is the exit value of the process with pid <pid>. A return
# value of 127 means that there was no process <pid>, and a value of 128
# signals that the operation timed out.
#
function waitpid {
waitpid_PID=$1
waitpid_TIMEOUT=$2
waitpid_TIMEDOUT=0

trap 'echo "$PROGNAME: caught SIGALRM waiting for pid $waitpid_PID" >&2; wai
tpid_TIMEDOUT=1' 14

while [ true ]; do sleep $waitpid_TIMEOUT && kill -14 $$; done &

waitpid_ALARM=$!

wait $waitpid_PID 2>/dev/null

waitpid_STATUS=$?

kill -15 $waitpid_ALARM

wait $waitpid_ALARM 2>/dev/null

if [ $waitpid_TIMEDOUT -eq 1 ]; then
waitpid_STATUS=128
fi

return $waitpid_STATUS
} # waitpid






[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
HK


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-19-05 12:50 PM

Martin Carpenter wrote:
> Problem: I have a command that runs from the shell, from which I need to
> obtain stdout and stderr, and retain the return code ($?). Sometimes, this
> command will hang indefinitely, and therefore I'd like to be able to kill 
it
> after a specified time period. (Further detail at the foot of this post).

Just last Friday I had the same problem and for some reason did
not find this thread and the proposed solution by William Ahern.
I came up with my own solution. I dare to say it is better
commented :-). Tried it with bash, don't know if it works
with just an old sh. Take your pick:

Harald.

#!/bin/sh
 ########################################
################################
# Runs a command and kills it, if necessary, after a given timeout. If
# the command finishes earlier, this script also finishes earlier.
#
# Parameter:
# $1 - timeout in seconds
# $2 ... - command to run and its parameters and redirections
#
# Exit code:
#       0 - all went well
# 0<c<127 - job exited with this exit code
#   >=127 - job was preempted
#
# NOTE: Don't put this into a shell function. It may not work in
# circumstances where the shell using it runs several jobs in the
# background.
#
# (C) Harald Kirsch (Harald at pifpafpuf dontmissthedot de)
 ########################################
################################
#set -x

# enable job control
set -m

# Fetch the timeout from $1 and execute all other arguments in the
# background.
timeout="$1"; shift
eval "$@" &

# Arrange for a SIGUSR1 to kill the above job. We do not use a pid
($!),
# because it might be wrong. The %1, however, can not be mistaken.
trap 'kill -9 %1 1>/dev/null 2>&1' SIGUSR1

# Arrange for SIGUSR1 to be send to us after the timeout in order to
# trigger the above trap. The $$ uniquely identifies this very
# script, because we make sure not to exit before this timeout job
exits.
(sleep $timeout; kill -SIGUSR1 $$ 1>/dev/null 2>&1) &

# Wait for the subprocess that does the work to exit. It either exits
# because it is finished or because it was killed prematurely. By
# a %1 instead of a pid it even works if the process has already
exited.
wait %1
result=$?

# If the subprocess finished in time, the timeout background process
# may still be running, targeting the pid of this very script. Before
# we exit, we send it home.
kill -9 %2 1>/dev/null 2>&1

# make the exit code available
exit $result






[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
Martin Carpenter


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-20-05 12:49 PM


"Chuck Dillon" <spam@nimblegen.com> wrote:

> Use dtksh on Solaris 8 to get ksh93 compatibility...

Thanks. And I don't even need dt for this 








[ Post a follow-up to this message ]



    Re: alarm() functionality from the shell  
Martin Carpenter


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-20-05 12:49 PM


"Heiner Steven" <heiner.steven@nexgo.de> wrote:

>      http://www.shelldorado.com/scripts/cmds/timeout

Thank you for that - it's pretty much exactly what I was asking for. I have
a couple of tiny niggles:


1. Despite this line:

exec >/dev/null 0<&1 2>&1

under Linux 2.6.13, bash 2.05b.0(1), I still get:

Terminated

back at the prompt if the command lasts longer than the timeout. (Not a big
deal).


2. I chose a different sequence of signals for my C version:

You have: TERM; HUP; KILL

I chose: TERM; ABRT; KILL

I'd be slightly wary of HUP causing the process to do something odd, such as
respawn itself, after which the KILL might go a little awry.










[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 07:03 PM.      Post New Thread    Post A Reply      
Pages (2): [1] 2 »   Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register