Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Running script at exit time

17 views
Skip to first unread message

Derek Fountain

unread,
Jan 16, 2008, 4:30:48 AM1/16/08
to
Is it possible to have a proc run automatically when a script exits?
Like Perl's END block?

I can reimplement the exit procedure, but that doesn't get run if the
script exits with an error, or if the script writer just lets the script
end without calling exit.

Is there a bulletproof solution that can guarantee a proc will
definitely be run at exit time?

Bryan Oakley

unread,
Jan 16, 2008, 6:54:56 AM1/16/08
to

The way I do it is to write my scripts like this:

proc main {} {...}
main

You could easily add more code after the call to main, and/or wrap the
call to main in a catch. You would probably need to do that (wrap it in
a catch) to get that guarantee you are looking for.

If you are talking abut Tk scripts you can bind to the <Destroy> event
of ".".

Derek Fountain

unread,
Jan 16, 2008, 8:32:44 AM1/16/08
to
> The way I do it is to write my scripts like this:
>
> proc main {} {...}
> main
>
> You could easily add more code after the call to main, and/or wrap the
> call to main in a catch. You would probably need to do that (wrap it in
> a catch) to get that guarantee you are looking for.
>
> If you are talking abut Tk scripts you can bind to the <Destroy> event
> of ".".

Hmm, yes, that would work, with a catch wrapping the main. It's a bit of
a shame that the language doesn't give you the feature itself though.

I'm maintaining an extended version of Tcl which a team of people use to
develop test scripts. Some are complaining that if their script dies due
to some unforeseen circumstances (which happen a lot around here!), the
log doesn't get flushed properly and they lose the last bit of
information - which is invariably the bit they need to see why the test
failed.

Ideally I'd like the library call that opened the log file to put in
place something that will automatically close it when the script exits,
like I do with my equivalent Perl libraries. Telling my testers, who
aren't hot Tclers, to use the technique you describe is possible but not
ideal.

But if that's the best the language can offer it'll have to do, unless I
hack the core, which is looking like a good option at the moment.

Helmut Giese

unread,
Jan 16, 2008, 9:17:26 AM1/16/08
to
Hi Derek,

>Hmm, yes, that would work, with a catch wrapping the main. It's a bit of
>a shame that the language doesn't give you the feature itself though.
>
>Ideally I'd like the library call that opened the log file to put in
>place something that will automatically close it when the script exits,
after the 'catch main' you could add something like
if { [info commands atExit ne ""] } {
atExit
}
and if your library adds a functtion 'atExit' it will get called at
the end.
Best regards
Helmut Giese

Christian Gollwitzer

unread,
Jan 16, 2008, 10:02:15 AM1/16/08
to
Derek Fountain schrieb:

>> The way I do it is to write my scripts like this:
>>
>> proc main {} {...}
>> main
>>
>> You could easily add more code after the call to main, and/or wrap the
>> call to main in a catch. You would probably need to do that (wrap it
>> in a catch) to get that guarantee you are looking for.
>>
>> If you are talking abut Tk scripts you can bind to the <Destroy> event
>> of ".".
>
> Hmm, yes, that would work, with a catch wrapping the main. It's a bit of
> a shame that the language doesn't give you the feature itself though.
>
> I'm maintaining an extended version of Tcl which a team of people use to
> develop test scripts. Some are complaining that if their script dies due
> to some unforeseen circumstances (which happen a lot around here!), the
> log doesn't get flushed properly and they lose the last bit of
> information - which is invariably the bit they need to see why the test
> failed.

not sure, if it works - but try to set an unset trace to some global
variable. It should be called when the script finishes.

Christian

Donal K. Fellows

unread,
Jan 16, 2008, 11:06:53 AM1/16/08
to
Derek Fountain wrote:
> I can reimplement the exit procedure, but that doesn't get run if the
> script exits with an error, or if the script writer just lets the script
> end without calling exit.

I think you'll find it does. What it won't catch is a full-blown crash.
Here's an [atExit] that works for me with 8.5.0...

set exitLambdas {}
rename exit _exit
proc exit {{code 0}} {
global exitLambdas
foreach l $exitLambdas {
if {[catch {apply $l $code} msg]} {
puts stderr $msg
}
}
_exit $code
}
proc atExit lambda {
global exitLambdas
lappend exitLambdas $lambda
return
}

Donal.

Donald G Porter

unread,
Jan 16, 2008, 11:13:03 AM1/16/08
to

Derek Fountain wrote:
>> I can reimplement the exit procedure, but that doesn't get run if the
>> script exits with an error, or if the script writer just lets the
>> script end without calling exit.

Donal K. Fellows wrote:
> I think you'll find it does.

It depends.

The tclsh program evals [exit] as Tcl_Main() comes to an end.
Other programs based on Tcl_Main() do likewise.

However, the wish program, and others built on Tk_Main()
do not do this. They call Tcl_Exit() directly with no
support for [exit] command redefinitions to have any effect.
Gotta go to Tcl_SetExitHandler() for those.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Donal K. Fellows

unread,
Jan 16, 2008, 11:30:57 AM1/16/08
to
Donald G Porter wrote:
> However, the wish program, and others built on Tk_Main()
> do not do this. They call Tcl_Exit() directly with no
> support for [exit] command redefinitions to have any effect.
> Gotta go to Tcl_SetExitHandler() for those.

I was under the impression that calling Tcl_Exit actually called [exit]
if it could. It seems I had that backwards. :-(

Donal.

bs

unread,
Jan 16, 2008, 4:50:23 PM1/16/08
to

Not sure if TIP 121 helps you or not...implemented in Tcl 8.5:
http://www.tcl.tk/cgi-bin/tct/tip/121.html

Derek Fountain

unread,
Jan 17, 2008, 2:55:54 AM1/17/08
to
> not sure, if it works - but try to set an unset trace to some global
> variable. It should be called when the script finishes.

Nice idea, but no, the trace command doesn't get called at script exit,
either normally or via an error.

Derek Fountain

unread,
Jan 17, 2008, 4:37:01 AM1/17/08
to
> I think you'll find it does. What it won't catch is a full-blown crash.
> Here's an [atExit] that works for me with 8.5.0...

So it does. Odd - I did test my how exit reimplementation behaved under
script error conditions and it didn't work. But your does under 8.4
(with slight tweakage) so I must have screwed up. :}

Thanks.

Larry W. Virden

unread,
Jan 17, 2008, 7:17:20 AM1/17/08
to
On Jan 16, 8:32 am, Derek Fountain <nom...@hursley.ibm.com> wrote:

>
> Hmm, yes, that would work, with a catch wrapping the main. It's a bit of
> a shame that the language doesn't give you the feature itself though.

Have you read over http://tip.tcl.tk/121 - I don't know if that meets
your need or not.


>
> Some are complaining that if their script dies due
> to some unforeseen circumstances (which happen a lot around here!), the
> log doesn't get flushed properly and they lose the last bit of
> information - which is invariably the bit they need to see why the test
> failed.

Why not set the log file stream to be non-buffered? That way, no
flushing is necessary.

MartinLemburg@Siemens-PLM

unread,
Jan 17, 2008, 9:53:55 AM1/17/08
to
Hi Christian,

you can use the trace capability to build your AtExit functionality.

Take a look at http://wiki.tcl.tk/20639.

The atExit functionality uses there execution traces, that work also
on internal tcl commands!

Best regards,

Martin Lemburg

On Jan 16, 4:02 pm, Christian Gollwitzer <Christian.Gollwit...@uni-

0 new messages