Operating System - Linux
1825775 Members
2160 Online
109687 Solutions
New Discussion

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

 
SOLVED
Go to solution
Christian Deutsch_1
Esteemed Contributor

$? -eq 0 after grep only works if set +x is in between?? (Points!)

Hi folks,

I have a REALLY weird problem with a shell script on HP-UX 11.23 Itanium.

In the script below, $? -eq 0 will only work after the grep if I interpose set +x. As soon as I comment out or delete set +x, $? -eq 0 will always return false.

Points will be assigned for helpful answers.

Also, I could not find the manpage explaining the difference between /sbin/sh and /usr/bin/sh. I would have thought /usr/bin/sh is "better", but /sbin/sh is larger, any ideas on this one? Otherwise I will post it as a separate question.

Thanks, Christian

#!/usr/bin/sh
#
# findlogs.sh - Search EATE logfiles for interesting information
#
# Author : Christian Deutsch
# Created : 21. 3.2007
# Modified: 21. 3.2007
#

# Get the name of this shell-script
SCRIPT=`basename $0`

NEWER=
STRING=

while [ ! -z "$1" ] # Parse parameters
do
case "$1" in
--newer) shift; NEWER=$1 ;;
--string) shift; STRING=$1 ;;
*) echo "Usage: $SCRIPT [--newer ] [--string ]"; exit 1 ;;
esac
shift
done

findlogs() # Find testcase logs (journal files) for the specified testcase name
{
count=0
fails=0
# rm -f /tmp/logs.$1
for dir in $DIRS
do
grep -q "$STRING" ${dir}/journal
#set +x
if [ $? -eq 0 ]
then
count=`expr $count + 1`
echo $dir
# echo $dir >> /tmp/logs.$1
grep \|FAIL ${dir}/journal
if [ $? -eq 0 ]
then
fails=`expr $fails + 1`
grep this_hostname $dir/condata | tail -1 | cut -d : -f2
fi
fi
done

echo
echo "Found $count files, $fails files with one or more fails in them."
}

# Main

cd $LATEST_EATE_REPORT_DIR

if [ "$NEWER" ]
then
DIRS=`find . -newer $NEWER -type d | grep -v -e ^.$ -e ./.executions`
else
DIRS=*
fi

findlogs

# eof
Yeshua loves you!
8 REPLIES 8
A. Clay Stephenson
Acclaimed Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

You don't have a really wierd problem; you don't even have a problem; this is a case of a script doing exactly as it is being told to do:

Hi folks,

I have a REALLY weird problem with a shell script on HP-UX 11.23 Itanium.

In the script below, $? -eq 0 will only work after the grep if I interpose set +x. As soon as I comment out or delete set +x, $? -eq 0 will always return false.

Points will be assigned for helpful answers.

Also, I could not find the manpage explaining the difference between /sbin/sh and /usr/bin/sh. I would have thought /usr/bin/sh is "better", but /sbin/sh is larger, any ideas on this one? Otherwise I will post it as a separate question.

Thanks, Christian

#!/usr/bin/sh
#
# findlogs.sh - Search EATE logfiles for interesting information
#
=


grep -q "$STRING" ${dir}/journal
#set +x
if [ $? -eq 0 ]
then
If it ain't broke, I can fix that.
Peter Godron
Honored Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

Hi,
I normally assign the $? to a variable, rather than using it in the if statement.

grep \|FAIL ${dir}/journal

a=$?
echo "[$a]"
if [ $a -eq 0 ]
.
.
Patrick Wallek
Honored Contributor
Solution

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

/usr/bin/sh and /sbin/sh are the same shell, the POSIX shell.

The difference is that /sbin/sh is statically linked, meaning that all libraries necessary for it to function are linked into the executable. The /usr/bin/sh is dynamically linked, meaning it loads libraries from /usr/lib as they are needed.

This is important because /sbin/sh is root's default shell, and MUST remain roots default shell, because the shell must be usable BEFORE the /usr filesystem is mounted. This is why single-user mode works when you only have / available.

This is also why you will break the system if you ever change root's default shell to something other than /sbin/sh.

James R. Ferguson
Acclaimed Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

Hi:

Your observation does seem odd. You might also try:

# if [$? = "0" ]

As for '/usr/bin/sh' and '/sbin/sh' they are both the POSIX shell. THe difference is that '/usr/bin/sh' uses dynamic libraries whereas those for '/sbin/sh' are statically linked. This is the reason that you NEVER use anything but '/sbin/sh' for the root account, since during startup '/usr' isn't mounted!

The value of the '/usr/bin/sh' lies in its dynamic libraries. Their use reduces the overall memory footprint for multiple users.

Regards!

...JRF...

A. Clay Stephenson
Acclaimed Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

You don't have a really wierd problem; you don't even have a problem; this is a case of a script doing exactly as it is being told to do:


grep -q "$STRING" ${dir}/journal
#set +x
if [ $? -eq 0 ]

Note that you have "set +x" immediately before your test of ${?}. It is simply returning the status of the last statement/command -- namely the set itself.

What you should do is this:

grep -q "xxx" filea
STAT=${?} # capture the status immediately
set +x
if [[ ${STAT} - eq 0 ]]

Capturing ${?} in a variable is always a good technique because you then have it for things like error messages as well as evaluation.

Both /usr/bin/sh and /sbin/sh are fully functional and functionally equivalent versions of the POSIX shell. The difference is that /sbin/sh is a statically linked version of the shell so that no shared libraries are needed. Ask yourself, when in single-user mode and when only /stand and / are mounted, how would the startup scripts which run under a shell execute when the required shared libraries are in a filesystem that hasn't yet been mounted.
If it ain't broke, I can fix that.
Oviwan
Honored Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

Hey

don't set the set +x between the command and the check:

look at this:
oracle@blah:/home/oracle$ cd /oracle
oracle@blah:/oracle$ echo $?
0
oracle@blah:/oracle$ cd /oracle
oracle@blah:/oracle$ set +x
oracle@blah:/oracle$ echo $?
0
oracle@blah:/oracle$ cd /aslkdjf
sh: /aslkdjf: not found.
oracle@blah:/oracle$ echo $?
1
oracle@blah:/oracle$ cd /asldjf
sh: /asldjf: not found.
oracle@blah:/oracle$ set +x
oracle@blah:/oracle$ echo $?
0

Regards
Christian Deutsch_1
Esteemed Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

ok you win, I suspected that the set +x would fool me and in fact it did.

I'll close the post now.

Thanks for taking the time to answer, Christian
Yeshua loves you!
Christian Deutsch_1
Esteemed Contributor

Re: $? -eq 0 after grep only works if set +x is in between?? (Points!)

.
Yeshua loves you!