I am calling my common-lisp program via a shellscript which calls sbcl with the necessary parameters and I have to guarantee that anyhow the actual program finishes the call will end clean with some/none output.
My current solution looks like this:
sbcl --eval "(unwind-protect
(handler-case
(progn
(declaim #+sbcl(sb-ext:muffle-conditions style-warning))
(let ((*standard-output* (make-broadcast-stream)))
(ql:quickload \"module\"))
(eval (read-from-string \"(package:start)\"))) ;this starts the program
(error (err)
(FORMAT t \"Something went really wrong:~a~%\" err)
(sb-ext:exit)))
(sb-ext:exit))"
But in the following two szenarios it wont work:
sbcl --eval "(unwind-protect
(handler-case
(progn
(define-condition bad () ())
(error 'bad))
(error (err)
(FORMAT t \"Something went really wrong:~a~%\" err)
(sb-ext:exit)))
(sb-ext:exit))"
sbcl --eval "(unwind-protect
(handler-case
(progn
(labels ((rek () (rek)))
(rek)))
(error (err)
(FORMAT t \"Something went really wrong:~a~%\" err)
(sb-ext:exit)))
(sb-ext:exit))"
I am now wondering if there is another solution which will catch ANY possible outcome of a called program and will ensure that the sbcl call will exit clean?
For the first scenario a general catch which does not specify what to catch, would probably do the deal. The second scenario has to be able to cope with bugs/errors which would result in the low-level-debuger being called.
The --non-interactive
switch will ensure that SBCL never enters the debugger or the REPL. It's similar to passing --disable-debugger
and using --eval "(sb-ext:quit)"
. You can also customize sb-ext:*invoke-debugger-hook*
if you don't want it to print a backtrace in the event of an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With