Operating System - Linux
1752273 Members
5147 Online
108786 Solutions
New Discussion юеВ

Testing in Bourne shell vs POSIX shell

 
SOLVED
Go to solution
renarios
Trusted Contributor

Testing in Bourne shell vs POSIX shell

Hi all,

I have yet another Bourne shell vs POSIX shell question.

In a script I check the database status using the following statements:

# Check database status
STATUS=$(sqlplus -s </ as sysdba
set heading off feedback off
select status from v\$instance;
exit
EOF)

Now my question is:
When I test using the Bourne shell all works fine (see example 1), bur when I test the POSIX (preferred) way, it fails.

#example1
if [ ${STATUS} = "OPEN" ]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"$STATUS
exit
fi
The database started successfully!


#example2
if [[ ${STATUS} = "OPEN" ]]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"$STATUS
exit
fi
Database NOT open, status is: OPEN

An echo \'${STATUS}\' returns ' OPEN'
An echo \'"${STATUS}"\' returns '
OPEN'

What is the best way to use the POSIX testing method (and make working)

Thanks in advance,

Renarios
Nothing is more successfull as failure
16 REPLIES 16
Muthukumar_5
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

What are you getting on ${STATUS} Variable in both shells. Try as,

# Check database status
STATUS=$(sqlplus -s </ as sysdba
set heading off feedback off
select status from v\$instance;
exit
EOF)
echo ${STATUS}

Execute and revert with results.

Good scripting is as,

if [[ "${STATUS}" = "OPEN" ]]

hth.
Easy to suggest when don't know about the problem!
renarios
Trusted Contributor

Re: Testing in Bourne shell vs POSIX shell

Hi hth,
here are the results:
$>$STATUS=$(sqlplus -s <> / as sysdba
> set heading off feedback off
> select status from v\$instance;
> exit
> EOF)
$>echo ${STATUS}
OPEN

The problem still exists:
if [[ "${STATUS}" = "OPEN" ]]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"$STATUS
fi
Database NOT open, status is: OPEN

$>echo \'${STATUS}\'
' OPEN'
$>echo \'"${STATUS}"\'
'
OPEN'

If I test using if [[ "${STATUS}" = ' OPEN' ]] it also doesn't work

Any more ideas?

Cheers,
Renarios
Nothing is more successfull as failure
Muthukumar_5
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

After getting ${STATUS} variable do like,

echo ${STATUS} | od -dc

Change the check statement like,

if [ $(echo $STATUS | grep 'OPEN') = "OPEN" ]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"$STATUS
fi

# Note: Don't use exit when executing shell statements with script.

BTW: I am Muthukumar (hth - hope this helps)

hth.
Easy to suggest when don't know about the problem!
renarios
Trusted Contributor

Re: Testing in Bourne shell vs POSIX shell

Ehhhm whoops, sorry Muthukumar.

The "echo ${STATUS} | od -dc" returns the following:

echo ${STATUS} | od -dc
0000000 20304 17742 02560
O P E N \n
0000005

I didn't write the script myself, I'm only checking it on errors and rewriting it to POSIX. The exits in the script is another issue, but we'll solve that.
The option you gave is a good one.
Is there an option to use for the creation of the STATUS variable?
I know an option like:
# Remove leading CR/LF
status=$(echo ${STATUS} | cut -c 1-)
But that's very quick and dirty. Is there another way for that?

Thanks,

Renarios
Nothing is more successfull as failure
VEL_1
Valued Contributor

Re: Testing in Bourne shell vs POSIX shell

Hi,


To remove CR

str=$(echo $str| tr -d '\r\032')

To remove LF

str=$(echo $str | tr -d '\r')
VEL_1
Valued Contributor

Re: Testing in Bourne shell vs POSIX shell



Sorry for confusing. try to use:

sed 's/^M$//'

Muthukumar_5
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

I am not sure with od -dc output. It is correct as,

# echo 'OPEN' | od -dc
0000000 20304 17742 02560
O P E N \n
0000005

Actually It is not good to get "STRING" as return value in shell scripting (my idea)!!. Try to use number for that easily as,


# Check database status
STATUS=$(sqlplus -s </ as sysdba
set heading off feedback off
select status from v\$instance;
exit
EOF) | grep -q 'OPEN'

if [ $? -eq 0 ]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"$STATUS
exit
fi
# END

$? is the variable returns value of the previous command execution. I am requesting you to use it. Use like $? or ${?}

May be problem with sh binary? Don't know.

hth.

Easy to suggest when don't know about the problem!
Ralph Grothe
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

As for the stripping of line feeds proposed by raj,
afaik, the Unix line feed is \n or \012
(man ascii), so the transliteration should in my opinion read

echo "$STATUS" | tr -d \\012

Besides, there isn't such big difference between the HP Posix Shell and the Bash.
You could as well avoid word splitting in Bash in your test blocks by usage of the twin square brackets
e.g.
if [[ $STATUS = OPEN ]]; then ...
Madness, thy name is system administration
Bill Hassell
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

Are you actually using the Bourne shell to test? In HP-UX, the Bourne shell is found in /usr/old/bin/sh and unless you specify the desired interpreter (shell) as your first line, the script will be run by whatever shell you are using at the moment. Always code the interpreter:

#/usr/old/bin/sh

or

#/usr/bin/sh

And just like with Bourne, POSIX, Korn and BASH, you can trace the execution with set -x or run the script with the interpreter and the -x flag as in:

/usr/old/bin/sh -x myscript

Note that tracing is always sent to stderr so to pipe everything into more or pg, redirect stderr:

/usr/bin/sh -x myscript 2>&1 | more

As far as the OPEN not working, the result of the program is TWO lines, not one. Although octal it's a pain to read, it's clear that your sqlplus program returns a blank line followed by OPEN. So there are several ways to solve this:

STATUS=$(echo "$STATUS | tail -1)

but this suffers from the prblem that the sqlplu program may be unstable (not dependable to always write a blank line), so just use grep:

if echo "$STATUS" | grep -q OPEN
then
echo "Database is OPEN"
else
echo "Database not open, status is \""$STATUS"\""
fi

(note the use of extra " in the not-open status--it will delimit the beginning and end of the actual string)

BTW: A much, much easier way to decode strings is to use hex:

echo "$STATUS" | xd -xc

Note that od and xd are the same program, so you can also use this:

echo "$STATUS" | od -xc


Bill Hassell, sysadmin