Bug 1268178

Summary: SH_LEVEL declared integer but treated as string for interactive shells in ksh93u+
Product: Red Hat Enterprise Linux 6 Reporter: Frank Hirtz <fhirtz>
Component: kshAssignee: Siteshwar Vashisht <svashisht>
Status: CLOSED NOTABUG QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: high Docs Contact:
Priority: unspecified    
Version: 6.7CC: jruemker
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-08-12 18:42:25 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1269194    

Description Frank Hirtz 2015-10-02 02:24:49 UTC
Description of problem:
We have the following piece of code in our interactive shell environment initialization:

#     
# Provide protection for aggressive job control users
#
integer SH_LEVEL
if (( SH_LEVEL <= 0 )); then
  alias suspend='echo "This is a login shell."'
fi
export SH_LEVEL=SH_LEVEL+1


This breaks with ksh 93u+ as shipped by Redhat in RHEL6 since RHEL6.5 (ksh-20120801-10.el6.x86_64.rpm) - SH_LEVEL appears to be treated as a string (the integer declare notwithstanding) and the resulting environment contains:

$ echo $SH_LEVEL
SH_LEVEL+1

 The previous versions up to, ksh-20100621-19.el6.x86_64.rpm, do the arithmetics with undef==0 and make SH_LEVEL=1 (for a toplevel interactive).

Where are you experiencing the behavior?  What environment?

SH_LEVEL should be treated as integer / numerical value, and should not be set to the string "SH_LEVEL+1" by the above environment initialization code when using the ksh-20120801* (ksh 93u+) versions of the package.

The ksh-20100621* versions correctly set SH_LEVEL to a numerical value while the ksh-20120801* versions set it to the string "SH_LEVEL+1".

It appears that the regression got introduced between ksh93u and ksh93u+; Oracle ships 93u, in Solaris,

  version         sh (AT&T Research) 93u 2011-02-08

and that is unaffected by the issue, while we have an internal build of ksh that matches the "new" one from RHEL6.5 and above,

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

that show the same behaviour change.
The "COMPATIBILITIES" file in usr/share/doc/ksh isn't mentioning anything, and nothing in the changelog is obvious

Version-Release number of selected component (if applicable):

Reproducible with any of:

ksh-20120801-10.el6.x86_64.rpm
ksh-20120801-10.el6_5.11.x86_64.rpm
ksh-20120801-10.el6_5.12.x86_64.rpm
ksh-20120801-10.el6_5.13.x86_64.rpm
ksh-20120801-10.el6_5.3.x86_64.rpm
ksh-20120801-10.el6_5.4.x86_64.rpm
ksh-20120801-10.el6_5.5.x86_64.rpm
ksh-20120801-10.el6_5.6.x86_64.rpm
ksh-20120801-10.el6_5.7.x86_64.rpm
ksh-20120801-10.el6_5.8.x86_64.rpm
ksh-20120801-10.el6_5.9.x86_64.rpm
ksh-20120801-21.el6.1.x86_64.rpm
ksh-20120801-21.el6.x86_64.rpm
ksh-20120801-21.el6_6.2.x86_64.rpm
ksh-20120801-21.el6_6.3.x86_64.rpm
ksh-20120801-27.el6.x86_64.rpm
ksh-20120801-28.el6.1.x86_64.rpm
ksh-20120801-28.el6.x86_64.rpm
ksh-20120801-28.el6_7.3.x86_64.rpm
ksh-20100621-12.el6.x86_64.rpm
ksh-20100621-12.el6_2.1.x86_64.rpm
ksh-20100621-16.el6.x86_64.rpm
ksh-20100621-19.el6.x86_64.rpm
ksh-20100621-19.el6_4.3.x86_64.rpm
ksh-20100621-19.el6_4.4.x86_64.rpm
ksh-20100621-6.el6.x86_64.rpm

How reproducible:

Simpler testcase:

It appears that "exporting variable assignments" are treated differently in ksh93u+ and ksh93t+. Something like:

integer MYFOO; export MYFOO=HOME+1234; echo $MYFOO; unset MYFOO

gives an "arithmetic error" message (and no variable assignment made to MYFOO) from the older ksh93t+ showing that the expression 'HOME+1234' is evaluated, while this happily assigns the string "HOME+1234" to MYFOO on ksh93u+.

If you change it to:

integer MYFOO; MYFOO=HOME+1234; export MYFOO; echo $MYFOO; unset MYFOO

the result is the same on both ksh93u+ and ksh93t+, in my case:

...ksh: /v/global/user/h/ho/hofmann: arithmetic syntax error


I.e. in short, the behavior of:

export MYFOO=<whatever>

on ksh93t+ is the same as that of:

MYFOO=<whatever>; export MYFOO

i.e ksh93t+ evaluates the expression <whatever> before assigning the value to the variable, while on ksh93u+, it only does string substitution but not evaluation, like export MYFOO="<whatever>"


This is a very significant behaviour difference.

Additional info:

We've got a number of shell scripts that use SH_LEVEL for recursion detection and they break on upgrade to the default ksh in RHEL6.5 and later.

Comment 1 Michal Hlavinka 2016-01-07 10:44:42 UTC
This is intentional behaviour as it was explicitely changed by upstream:

12-04-27  A bug in which old attributes were not cleared when assigning a
	  value using typeset has been fixed.

btw, "export" is an alias for "typeset -x"

Comment 2 John Ruemker 2016-08-12 18:42:25 UTC
The customer case reporting this problem was closed some time ago, and Comment #1 makes clear this was intentional design.  As such, I am closing this case out.  If there is a customer with ongoing concerns about this behavior, feel free to reopen this bug with details for further consideration.