Solaris "read -e"

Hi,

Why does this piece of script work on a Solaris 10 test.sh script but if I include it in the request script of packaging generates errors?

        
until [ -n "$CONFIGCACHE" ] && [ -n "$prompt" ] && [ -z `echo $CONFIGCACHE | /usr/xpg4/bin/sed -e 's/[YN]//g' ` ]
        do
                echo -n "Do you want to configure Cache Manager? [Y/N] "
                read -e -n 1 CONFIGCACHE
                echo ""
                prompt=1
        done

In the request script it stops at read -e:
-n Do you want to configure Cache Manager? [Y/N]
/var/tmp//installe5aOBQ/checkinstallh5aOBQ: -e: is not an identifier
pkgadd: ERROR: request script did not complete successfully

If I replace "read -e -n 1" with simple read I get
/var/tmp//install0UaOMQ/checkinstall3UaOMQ: test: argument expected
pkgadd: ERROR: request script did not complete successfully

Thanks,
Bianca

That must be run by bash.

It's a horrible piece of code that would be better written, also for bash, as:

printf "Do you want to configure Cache Manager? [Y/N] "
while :
do
  read -sn1  CONFIGCACHE
  case $CONFIGCACHE in
    [YNyn]) break ;;
  esac
done
echo

For this I get

Do you want to configure Cache Manager? [Y/N] /var/tmp//installltaiLW/checkinstallotaiLW: -sn1: is not an identifier
pkgadd: ERROR: request script did not complete successfully

Why don't the read parameters work properly ? I have same with read -e , read -n 1, etc.

You must run it with bash; no other shell will work for that code.

I set #!/bin/bash in the scripts.

In a separate script it works .. and in the request script doesn't work that's why is so frustrating.

What command line do you use to run it?

And please post the entire script that contains it.

And post the output of:

/bin/bash --version

Hi

bash-3.00# /bin/bash --version
GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10)
Copyright (C) 2004 Free Software Foundation, Inc.
bash-3.00# /usr/bin/bash --version
GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10)
Copyright (C) 2004 Free Software Foundation, Inc.

In the scripts I use #!/bin/bash

The request script I use in the package is pretty long. I refer only to this section as it is not related to nothing before.

So if I run it separate it works.

If I run it in the request script:

  1. I have to delete read parameters -e -n 1 as they generate errors
  2. Then I get
    /var/tmp//install59a41W/checkinstall89a41W: test: argument expected
    pkgadd: ERROR: request script did not complete successfully

bash-3.00# cat test.sh
#!/bin/bash

    until [ -n "$CONFIGCACHE" ] && [ -n "$prompt" ] && [ -z \`echo $CONFIGCACHE | sed -e 's/[YN]//g' \` ]
    do
            echo -n "Do you want to configure Cache Manager? [Y/N] "
            read -e -n 1 CONFIGCACHE
            echo ""
            prompt=1
    done

bash-3.00# ./test.sh
Do you want to configure Cache Manager? [Y/N] Y

bash-3.00#

Thanks,
Bianca

If it works when run separately, but not in the larger script then obviously the problem is related to something before.

Then it is not being run by bash!

(There is no point to using the -e option with -n1; -e enables line editing, but since you are only allowing a single character to be entered, it is not possible to edit the line.)

[color=red]Please put code inside

 tags.



bash-3.00# cat test.sh
#!/bin/bash

[/quote]

[indent]
The following code is bloated and convoluted; that can make debugging difficult. Please replace it with the snippet I suggested before.

And I repeat: [b]What command line do you use to run it?

Hi,

Of course that I tried your suggestion. Your code generates errors as well because of read parameters.

But you might be right about the fact that the script is not run by bash.
My "request" script is part of the packaging developed for an application. So I don't really know how it is run.

Still I read a doc that specified this about packaging scripts:
"The script is composed of Bourne shell commands.
The script's file permissions should be set to 0644.
The script does not need to contain the shell identifier (#! /bin/sh)."

So it uses /bin/sh and even if I put /bin/bash it disregards that.

Bianca

If the permissions are 0644, then it isn't being treated as an executable script, but as the argument to a shell command, and it will be run by whatever shell is used on the command line, e.g., /bin/sh scriptname. (That's why I asked how it was being run.)

If you really want to allow the user to enter just one key, either have the packaging script call a wrapper that does use bash to execute the script, or use dd instead of read.

printf "Do you want to configure Cache Manager? [Y/N] "
[ -t 0 ] && { _STTY=`stty -g`; stty -icanon -echo min 1; }
while :
do
  CONFIGCACHE=`dd bs=1 count=1 2>/dev/null`
  case $CONFIGCACHE in
    [yYnN]) break ;;
  esac
done
[ -t 0 ] && stty $_STTY
echo "$CONFIGCACHE"

Thanks for the solution.

But still how could I fix the read problem, as I read a lot of parameters like this:

   
APPLOGDIR1="${DIR}/log"
echo "Please type the XAC Log Directory: (current value: $APPLOGDIR1)"
read APPLOGDIR1

If the user hits ENTER here the value of APPLOGDIR1 is set to "".

I Linux I have a function that solves that but doesn't work on Solaris:

readDefault()
{
    ARGS=""
    N=1
    LOCALBUF=""
    until  [ $N -eq $# ]
    do
        eval ARG=\${$N}
        ARGS=" $ARGS $ARG"
        N=`expr $N + 1`
    done
    read $ARGS LOCALBUF
    if [ -n "$LOCALBUF" ]
    then
        VARNAME=${!#}
        export $VARNAME=$LOCALBUF
    else
        echo "Using current value."
    fi
}

And I call it like this

echo "Please type the path of the Log directory: (current value: $SB_LOGDIR1)"
readDefault -e SB_LOGDIR1

But I didn't managed to make it work on Solaris.

Bianca

If you use the -e option, you must run the script with bash. No other shell has it.

I removed the -e parameter. Still .. If I hit ENTER the variable maintains the it initial value, if I enter a new value it generates errors:

bash-3.00# ./test1.sh
Please type the Log Directory: (current value: /app/)
sss
./test1.sh: bad substitution
bash-3.00#

This is bash only:

VARNAME=${!#}

You have bash on your Solaris box, so why not use it?

This is POSIX, but doesn't work in Bourne shell:

export $VARNAME=$LOCALBUF

.....

I hope you don't use this on your Linux box:

N=`expr $N + 1`

Bash (like all POSIX shells) has arithmetic built in:

N=$(( $N + 1 ))

I would use bash but how? The script is run by /bin/sh (this is out of my control) so I can't change that to bash.

PS: Thanks a lot for your time.
Bianca