Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Is there a way to put a timeout on a function?

On Mon, Aug 31, 2020 at 8:00 AM Rudi C <rudiwillalwaysloveyou@xxxxxxxxx> wrote:
> I need to limit the execution time of arbitrary zsh functions. Is there a way to achieve this? I'm ok with just adding a time limit to all the external commands, but I do not know how to do that. (I don't want to manually prefix all my commands with the GNU timeout command.)

Here's a basic outline; you'll have to fiddle with it to get the
details as you want:

# This is the default, but for clarity
 #  Prevent the command from running twice
 setopt localoptions ERR_EXIT
 # Set up the timeout
 # Background so parent can wait for timer
 (){ eval "${ZSH_DEBUG_CMD}"; kill $timer } &
 wait $timer && kill $victim

Note that this prevents anything from changing the state of the
current shell, so be careful experimenting with it.  One of the things
you probably need to "fiddle with" is to have this function return
BEFORE it sets ERR_EXIT for any command that SHOULD run in the current
shell.  Another is that this buries the exit status of the command, so
you need a way to capture it.

> On a sidenote, I would also like to make the shell stop forcefully (like when a glob fails) if it doesn't find an external command. I thought maybe these two problems might have similar solutions. Is prexec viable for them? Does preexec even work for noninteractive scripts?

Preexec and precmd are strictly for interactive shells.

Another potentially dangerous solution:

command_not_found_handler() {
 builtin print "command not found: $*"
 builtin kill -USR1 $$
TRAPUSR1() { exit 1 }

Aside to -workers:  I've had this go into an infinite recursion if the
TRAPUSR1 definition precedes the command_not_found_handler definition
and/or the "builtin" prefix is not used.  This seems odd, but is not
reliably reproducible.

Messages sorted by: Reverse Date, Date, Thread, Author