[comp.sys.hp] Bug in HP's /bin/sh?

montnaro@spyder.crd.ge.com (Skip Montanaro) (02/09/90)

The following short Bourne shell script works fine under SunOS 4.0.3 and
Stellix 2.0, but fails under HPUX 6.5.

----------
#!/bin/sh

dbg () {
    echo "$@" 1>&2
}

catfile () {
    dbg \>scanlog
    cat $@
    dbg \<scanlog
}

catfile $0
----------

On the Stellar and Sun, executing the above script yields:

----------
% ./foo
>scanlog
#!/bin/sh

dbg () {
    echo "$@" 1>&2
}

catfile () {
    dbg \>scanlog
    cat $@
    dbg \<scanlog
}

catfile $0
<scanlog
%
----------

On the HP, it yields:

----------
% ./foo
>scanlog
cat: cannot open >scanlog
<scanlog
----------

Apparently there is only a single argument vector shared by functions under
HP's version of /bin/sh, so calling a function from within another function
ruins the argument vector to the first. Is this fixed in 7.0? The workaround
is to save the argument vector in a separate variable:

----------
catfile () {
    argv="$@"
    dbg \>scanlog
    set $argv
    cat $@
    dbg \<scanlog
}
----------

Unfortunately, this isn't too general. Any other ideas?

Thx,
--
Skip (montanaro@crdgw1.ge.com)

chet@cwns1.INS.CWRU.Edu (Chet Ramey) (02/09/90)

In article <MONTNARO.90Feb8142952@spyder.crd.ge.com>,
montnaro@spyder.crd.ge.com (Skip Montanaro) writes:

> Apparently there is only a single argument vector shared by functions under
> HP's version of /bin/sh, so calling a function from within another function
> ruins the argument vector to the first. Is this fixed in 7.0? The workaround
> is to save the argument vector in a separate variable:

This is true for all versions of /bin/sh descended from the System V.2 sh,
including Ultrix /bin/sh5, SunOS 3.x sh, and a few others.  There is a
single level of argument saving in the System V.3 sh, from which the SunOS
4.x sh (and, I would assume, the Stellix 2.0 sh) is derived.  A single
level of saving is sufficient, since recursive functions are disallowed. 

(Obligatory plug :-)

Bash (the GNU Bourne-Again SHell) allows recursive functions and correctly
saves the dollar variables.  Look for version 1.05 soon.

Chet Ramey				"Can't you pay a grad student to 
Network Services Group			 read the manual for you?"
Case Western Reserve University			-- Bill Wisner,
chet@ins.CWRU.Edu				   	to Peter Honeyman

rpt@hpfcdc.HP.COM (Rich Testardi) (02/10/90)

You might try using /bin/ksh -- it gives each function its own argument
list.  Ksh also allows functions to have *local* variables thru the use of
the "typeset" built-in command.

If you are stuck using /bin/sh, you might adopt the convention of always
assigning the function's parameters to uniquely named shell variables --
I typically prefix all variable names with the name of the function (or
an abbreviation) in which they are declared.

For example:

Foo()
{
  Foo_firstArg=$1
  Foo_secondArg=$2

  # possibly call other functions
  # use Foo_firstArg and Foo_secondArg
}

-- Rich Testardi