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

[ksh] trap issue

23 views
Skip to first unread message

Janis Papanagnou

unread,
Apr 27, 2017, 1:41:08 PM4/27/17
to
I want to distinguish errors from quits using traps like this

trap 'printf "An error occurred!\n" ; exit 8' ERR
trap 'printf "Execution aborted!\n" ; exit 9' HUP INT QUIT TERM
sleep 3 ; diff x

but even with a ^C I only get the first trap triggerd with

$ ksh --version
version sh (AT&T Research) 93u+ 2012-08-01

Above code behaves as expected with bash and zsh. Is that a ksh bug?
What would be a sensible workaround, preferably one that works also
in bash and zsh, or functional code conforming to POSIX standard?

Janis

Kaz Kylheku

unread,
Apr 27, 2017, 2:43:32 PM4/27/17
to
On 2017-04-27, Janis Papanagnou <janis_pa...@hotmail.com> wrote:
> I want to distinguish errors from quits using traps like this
>
> trap 'printf "An error occurred!\n" ; exit 8' ERR
> trap 'printf "Execution aborted!\n" ; exit 9' HUP INT QUIT TERM
> sleep 3 ; diff x
>
> but even with a ^C I only get the first trap triggerd with
>
> $ ksh --version
> version sh (AT&T Research) 93u+ 2012-08-01

Is there any difference if you replace the sleep with a purely internal
action like "while true ; : done"?

Is there any difference if you reorder the trap commands?

Wildly unlikely: maybe they are registered in some ordered list, and if
both situations apply (command failed because of Ctrl-C), only the first
eligible trap is processed. (Grasping-at-straws wild assed guess).

> Above code behaves as expected with bash and zsh. Is that a ksh bug?
> What would be a sensible workaround, preferably one that works also
> in bash and zsh, or functional code conforming to POSIX standard?

In the past I have written scripts which trapped failing commands,
had a handler for an interrupt, and had exit cleanup actions also.

I did that using "set -e" to catch the failing commands rather than
the ERR trap, and an EXIT trap for the common cleanup action.

Perhaps these pieces can cob together an acceptable workaround here?

This program still behaves how we want on bash: how is it on your ksh?


sig_was_caught=

sig_handler()
{
sig_was_caught=y
exit 9
}

exit_handler()
{
saved_status=$?
if [ $sig_was_caught ] ; then
printf "Execution aborted!\n"
exit $saved_status
elif [ $saved_status -ne 0 ] ; then
printf "An error occurred!\n"
exit 8;
fi
}

trap exit_handler EXIT
trap sig_handler HUP INT QUIT TERM
sleep 3; false


If that works, it boils down to whether "set -e" meets the requirements
that you're trying to satisfy with "trap ... ERR".

Janis Papanagnou

unread,
Apr 27, 2017, 3:47:15 PM4/27/17
to
On 27.04.2017 20:43, Kaz Kylheku wrote:
> On 2017-04-27, Janis Papanagnou <janis_pa...@hotmail.com> wrote:
>> I want to distinguish errors from quits using traps like this
>>
>> trap 'printf "An error occurred!\n" ; exit 8' ERR
>> trap 'printf "Execution aborted!\n" ; exit 9' HUP INT QUIT TERM
>> sleep 3 ; diff x
>>
>> but even with a ^C I only get the first trap triggerd with
>>
>> $ ksh --version
>> version sh (AT&T Research) 93u+ 2012-08-01
>
> Is there any difference if you replace the sleep with a purely internal
> action like "while true ; : done"?

In ksh sleep is already an internal command...

$ whence -a sleep
sleep is a shell builtin
sleep is /bin/sleep
sleep is an undefined function

>
> Is there any difference if you reorder the trap commands?

Nope.

>
> Wildly unlikely: maybe they are registered in some ordered list, and if
> both situations apply (command failed because of Ctrl-C), only the first
> eligible trap is processed. (Grasping-at-straws wild assed guess).

I suppose I would need to examine the ksh source code to answer that.
Thanks. That code works also in ksh (and solves the issue [or ksh bug?]).

>
> If that works, it boils down to whether "set -e" meets the requirements
> that you're trying to satisfy with "trap ... ERR".

Hmm.. - generally I would want to avoid side effects. In the specific code
where I need it it would be okay, though, but the current script is also
simple enough that I could also just change the interpreter to bash or zsh,
which would remove the necessity of using comparably bulky additional code,
but my preference is usually ksh. - Still pondering...

Janis

Janis Papanagnou

unread,
Apr 27, 2017, 8:41:30 PM4/27/17
to
On 27.04.2017 21:47, Janis Papanagnou wrote:
> On 27.04.2017 20:43, Kaz Kylheku wrote:
>> On 2017-04-27, Janis Papanagnou <janis_pa...@hotmail.com> wrote:
>>> I want to distinguish errors from quits using traps like this
>>>
>>> trap 'printf "An error occurred!\n" ; exit 8' ERR
>>> trap 'printf "Execution aborted!\n" ; exit 9' HUP INT QUIT TERM
>>> sleep 3 ; diff x
>>>
>>> but even with a ^C I only get the first trap triggerd with
>>>
>>> $ ksh --version
>>> version sh (AT&T Research) 93u+ 2012-08-01
>>
>> Is there any difference if you replace the sleep with a purely internal
>> action like "while true ; : done"?
>
> In ksh sleep is already an internal command...
>
> $ whence -a sleep
> sleep is a shell builtin

There's obviously a difference in behaviour between internal commands
and syntactical shell contructs; it was possible to get the signal trap
triggered in ksh if a syntactical shell construct is used instead of
the sleep builtin. - Not that I understand how that would help me with
ksh's behaviour here...

Janis

> [...]


0 new messages