1

I am kind of stuck with the below script where I would like to give a message on successful completion of the command but, at the same time if the its not successful then it should move on.

We have Oracle servers and below databases are 3 node rac servers. What I would like to archive is when I shutdown the instance on node 1 say, TEST11 it does not show the output on successful completion of the command. Else, it will throw an error, So I would like to record that error in a file and as well as echo whether it went successful or errored.

for DBI  in TEST11 TEST21 TEST31 TEST41
do
DB=$(echo -n $DBI | head -c -1)
echo $DB
export ORACLE_SID=$DBI
export ORACLE_HOME=`grep "^${DBI}:" /etc/oratab | cut -d: -f2 -s`
$ORACLE_HOME/bin/srvctl stop instance -d $DB -i $DBI
done

Thanks MohammedDBA

1

2 Answers 2

1

In bash $? gives you the return code of the previous command. If the previous command was successfull the return code is zero else non-zero.

In the following example, I am searching for a string in a file with both success and failure case. You can use this logic in your script.

Contents of my script test.sh

grep "grapes" file1 > /dev/null

if [ $? -eq 0 ]
then
    echo "Success. Perform success action"
else
    echo "Failure.. Do Failure action"
fi

Following is sample execution:

#cat file1
apple
grapes

#sh test.sh
Success. Perform success action


#cat file1
apple

#sh test1
Failure.. Do Failure action
6
  • Awesome, Let me try and see the magic, Than you #TheGeek Commented May 15, 2018 at 5:53
  • @Mohammeddba, please vote for my answer if this works.
    – TheGeek
    Commented May 15, 2018 at 7:59
  • My apologies, Not sure how to do it. Let me know how can I vote on this! Commented May 28, 2018 at 22:46
  • @Mohammeddba, to accept an answer, please do as follows: Choose one answer that you believe is the best solution to your problem. To mark an answer as accepted, click on the check mark beside the answer to toggle it from greyed out to filled in. You may change which answer is accepted, or simply un-accept the answer, at any time.
    – TheGeek
    Commented Jun 1, 2018 at 2:46
  • The elif check is misleading. It's doing a $? comparison against the result of the if block ([ $? -eq 0 ]), rather than the previous command. This should replaced with else rather than then elif. This can be verified by turning it around: this says "success" even though both checks are verifying $? does not equal 0, but the second one succeeds because it checks the failing result of the first one: if [ $? -ne 0 ]; then echo "Failure"; elif [ $? -ne 0 ]; then echo "Success"; fi.
    – M. Justin
    Commented Mar 12, 2021 at 16:50
1

Assuming that srvctl returns a useful exit status to the calling shell, we may use that in an if statement in the script to output messages depending on whether the database was successfully shut down or not.

#!/bin/bash

export ORACLE_SID ORACLE_HOME

for ORACLE_SID in TEST{1..4}1
do
        # The database name is the same as the SID,
        # but with the last character removed.
        db=${ORACLE_SID%?}

        # Get the ORACLE_HOME directory by parsing /etc/oratab.
        ORACLE_HOME=$( awk -F : '$1 == ENVIRON["ORACLE_SID"] { print $2 }' /etc/oratab )

        # Try stopping the service.
        if "$ORACLE_HOME"/bin/srvctl stop instance -db "$db" -instance "$ORACLE_SID"
        then
                # Report success.
                printf 'DB "%s" on instance "%s" stopped\n' "$db" "$ORACLE_SID"
        else
                # Report failure, log to file.
                printf 'Failed stopping DB "%s" on instance "%s"\n' "$db" "$ORACLE_SID" |
                tee -a error.log >&2
        fi
done

The script above re-implements most of your own script in a portable manner, removes unnecessary calls to external utilities, does not use more variables than needed, and adds an if statement that either outputs a message about successfully stopping the service, or about failing to stopping the service. If the service is not stopped, the message about this is additionally added to a log file called error.log in the current directory.


A variant of the above script that avoids reading the whole of /etc/oratab in every iteration and instead parses the file in the loop, tests whether we've found an interesting ORACLE_SID, and otherwise skips to the next iteration. The if statement is identical to the first script.

#!/bin/bash

export ORACLE_SID ORACLE_HOME

while IFS=: read -r ORACLE_SID ORACLE_HOME
do
        # Skip uninteresting SIDs.
        [[ $ORACLE_SID != TEST[1-4]1 ]] && continue

        db=${ORACLE_SID%?}

        if "$ORACLE_HOME"/bin/srvctl stop instance -db "$db" -instance "$ORACLE_SID"
        then
                printf 'DB "%s" on instance "%s" stopped\n' "$db" "$ORACLE_SID"
        else
                printf 'Failed stopping DB "%s" on instance "%s"\n' "$db" "$ORACLE_SID" |
                tee -a error.log >&2
        fi
done </etc/oratab

You could delete all "bash-isms" from the above script by changing the [[ $ORACLE_SID != TEST[1-4]1 ]] test to

case $ORACLE_SID in (TEST[1-4]1) : ;; (*) continue; esac

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .