Operating System - Linux
1819792 Members
3087 Online
109607 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
renarios
Trusted Contributor

Re: Testing in Bourne shell vs POSIX shell

Hi Bill,
Since this script is executed by user oracle (non-root) I always code using the interpreter #!/usr/bin/sh. Is that correct?

I will use the following in my script (which according my information is correct POSIX ):
STATUS=$(echo $(sqlplus -s </ as sysdba
set heading off feedback off
select status from v\$instance;
exit
EOF) | tr -d \\012)

# Use double brackets (My favorit)
if [[ ${STATUS} = "OPEN" ]]
then
echo "The database started successfully!"
else
echo "Database NOT open, status is:"${STATUS}
#exit <-- rewrite to return
fi

Cheerio,

Renarios
Nothing is more successfull as failure
Bill Hassell
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

Correct. The standard shell for HP-UX is the POSIX shell and is found in /usr/bin/sh. Unfortunately, this is exactly the same name used in other Unix flavors for the Bourne shell, thus endless confusion. It's really hard to find Bourne to POSIX shell conversion problems. Korn and Bash are also POSIX compliant shells so they more than 95% identical.


Bill Hassell, sysadmin
Gregory Fruth
Esteemed Contributor

Re: Testing in Bourne shell vs POSIX shell

Perhaps you could just change the test to
[[ "$STATUS" = "OPEN\n" ]].

The thing I don't understand is how the
trailing newline is getting in there in the
first place. The $() construct is supposed to
strip it: (from the man page)

The standard output from a command enclosed in
parenthesis preceded by a dollar sign ($(...))
or a pair of grave accents (`...`) can be used
as part or all of a word; trailing newlines are
removed.

Arturo Galbiati
Esteemed Contributor
Solution

Re: Testing in Bourne shell vs POSIX shell

Hi renarios,
the problem is not related to teh shell, but to Oracle. You disable the header putting head off but not the new page. Instead of head off use pages 0 and SQL will retrun the status withou any control char:

Your code:
09:58 GPOP09BN hpbbnn1/home/oracle/> STATUS=$(sqlplus -s <> / as sysdba
> set head off feedback off
> select status from v\$instance;
> exit
> EOF)
10:00 GPOP09BN hpbbnn1/home/oracle/> echo "$STATUS"

OPEN
10:00 GPOP09BN hpbbnn1/home/oracle/>


my code:


10:01 GPOP09BN hpbbnn1/home/oracle/> STATUS=$(sqlplus -s <> / as sysdba
> set pages 0 feedback off
> select status from v\$instance;
> exit
> EOF)
10:01 GPOP09BN hpbbnn1/home/oracle/> echo "$STATUS"
OPEN
10:01 GPOP09BN hpbbnn1/home/oracle/>


This fix your problem about test.
Art

Muthukumar_5
Honored Contributor

Re: Testing in Bourne shell vs POSIX shell

Art,

Check this on following the execution of sql as,

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

You have to get "The database started successfully!" on getting ${STATUS} on POSIX shell.

Try it and post result.

hth.
Easy to suggest when don't know about the problem!
Arturo Galbiati
Esteemed Contributor

Re: Testing in Bourne shell vs POSIX shell

10:08 GPOP09BN hpbbnn1/home/oracle/> if [[ ${STATUS} = "OPEN" ]]
> then
> echo "The database started successfully!"
> else
> echo "Database NOT open, status is:"$STATUS
> exit
> fi
The database started successfully!
10:09 GPOP09BN hpbbnn1/home/oracle/>

Art
renarios
Trusted Contributor

Re: Testing in Bourne shell vs POSIX shell

Thanks Bill, for the feedback. It meens I was informed correctly!

Gregory, I already tried your test scenario, but that failed. I 'll dive into the man pages again.

Art, You scored the lot! That was solution on my issue.

Solution the reply from Art!

Thanks to all who assisted me on this issue.

Cheerio,

Renarios
Nothing is more successfull as failure