Need help in shell scripting

Hi, I am trying to execute below script but it is failing with error. Can someone please let me know the fix for this.

This is solaris server.

 if [ test $(find $BDUMP_DEST/alert_$ORACLE_SID.log -type f -size +5120c) ]

I am trying to find the alertlog size > 5KB. Below is the script.

 if [ test $(find $BDUMP_DEST/alert_$ORACLE_SID.log -type f -size +5120c) ]
                        then
                        cd $BDUMP_DEST
                        find . -name '*.gz' -mtime +90  | xargs rm -rf
                        cp alert_$ORACLE_SID.log alert_$ORACLE_SID.log_${NOW}
                        gzip alert_$ORACLE_SID.log_${NOW}
                        cat /dev/null > alert_$ORACLE_SID.log
                        cd ~
                        fi

Thanks,
Akhil

Making a few wild guesses at what you're trying to do, what operating system you're using, and hoping that you're using a shell that conforms to basic POSIX standard requirements, you might want to try the following replacement for your code:

if test "$(find "$BDUMP_DEST/alert_$ORACLE_SID.log" -type f -size +10)"
then	cd "$BDUMP_DEST"
	find . -name '*.gz' -mtime +90 -exec rm -f {} +
	cp "alert_$ORACLE_SID.log" "alert_$ORACLE_SID.log_${NOW}"
	gzip "alert_$ORACLE_SID.log_${NOW}"
	> "alert_$ORACLE_SID.log"
	cd
fi
1 Like

I dont mean to hijack, but Don, does the last 'cd' above return the shell to the previous spot then? For instance, the same as what a PUSHD and POPD do in DOS?

A plain cd would put you in your home directory, as defined by $HOME at the time you execute it. Using cd ~ has the same effect but could be extended so you can cd ~/.ssh to change to subdirectories of whatever $HOME points to.

Perhaps you would be safer to use pushd & popd or save the current directory to a variable and explicitly change to that at the end of the section.

Robin

Hi I am getting below error after modifying the script as told by you. I am also putting my full script here.

Errors:

bash-3.2$ sh "test.sh.bkp"
ALERTDB
/u01/app/oracle/product/10.2.0.4
HELLO
 /u01/app/oracle/admin/ALERTDB/bdump
 test.sh.bkp: null directory
bash-3.2$ ./test.sh.bkp
ALERTDB
/u01/app/oracle/product/10.2.0.4
HELLO
 /u01/app/oracle/admin/ALERTDB/bdump
find: stat() error /alert_ALERTDB.log: No such file or directory
bash-3.2$

Script:

  #!/bin/ksh
NOW=${NOW:-`date '+%Y%m%d_%H%M%S'`}
export NOW
runsql()
{
MQUERY=$1
$ORACLE_HOME/bin/sqlplus -s / as sysdba << EOF
set head off feedback off verify off trimspool on
spool OUT_FILE
$MQUERY
spool off
EOF
}
if [ -f /etc/oratab ]
        then
        FILE=/etc/oratab
else
        FILE=/var/opt/oracle/oratab
fi
cat $FILE | egrep -v '^#|\*|agent|CRS|IAS|GRID|NLSN|\+ASM' | sed '/^$/d' | while read LINE
do
if [ -n $LINE ]
then
        ORACLE_SID=`echo $LINE | awk -F: '{print $1}'`; export ORACLE_SID
        ORACLE_HOME=`echo $LINE | awk -F: '{print $2}'`; export ORACLE_HOME
        PATH=$ORACLE_HOME/bin:$PATH; export PATH
        echo $ORACLE_SID;
        echo $ORACLE_HOME
        /bin/ps -fu oracle | grep -w "ora_[a-z]*_$ORACLE_SID" > /dev/null
        if [ $? = 0 ] && [ -n $ORACLE_SID ] && [ -n $ORACLE_BASE ] && [ -n $ORACLE_HOME ]
        then
        echo "HELLO"
                else
                echo "DUMMY"
 fi
fi
QUERY3="select value from v\$parameter where NAME='background_dump_dest';"
                runsql "$QUERY3"
                BDUMP_DEST=`cat $OUT_FILE | sed -e "s/[[:blank:]]//g"`
               export BDUMP_DEST
if test "$(find "$BDUMP_DEST/alert_$ORACLE_SID.log" -type f -size +5120c)"
then
echo $BDUMP_DEST
cd "$BDUMP_DEST"
        find . -name '*.gz' -mtime +90 -exec rm -f {} +
        cp "alert_$ORACLE_SID.log" "alert_$ORACLE_SID.log_${NOW}"
        gzip "alert_$ORACLE_SID.log_${NOW}"
        cat /dev/null > "alert_$ORACLE_SID.log"
        cd
fi
done

Hi SIMMS7400 & Robin,
As Robin said, cd ~ (which is what aksdixs's script was using), cd "$HOME" , and cd all change directory to the user's home directory (unless something has unset HOME or set it to some other value).

In addition to using cd ~/directory to change to a directory in your home directory, you can also use cd ~user to change directory to the home directory of the user whose login ID is user and

cd ~user/some/directory

to change to some/directory in user's home directory. Of course, any of these may fail if user's home directory does not grant you search permission.

After a successful cd some/directory , the commands cd - and cd "$OLDPWD" will return you to the directory you were in before the previous cd command unless something has unset OLDPWD or set it to some other value). The OLDPWD variable maintained by the shell gives you one and only one level of what pushd and popd do on multiple levels in some shells (including csh and some versions of bash ). But dirs , pushd , and popd are not defined by the standards and are not available in many shells.

Hope this helps,
Don

1 Like

Please get rid of the unneeded cat (which was not there in the code I suggested). It doesn't do anything but put more load on your system and slow down your script.

And what do the diagnostics that I marked in red above tell us? They tell us that your script has set the BDUMP_DEST shell variable to an empty string! And, where did you set BDUMP_DEST ? You set it with:

                BDUMP_DEST=`cat $OUT_FILE | sed -e "s/[[:blank:]]//g"`

which contains another unneeded use of cat which I would have expected would have made your script hang waiting for input. Since OUT_FILE is a shell variable that is not defined anywhere in your script, $OUT_FILE will expand to an empty string, and cat $OUT_FILE will copy what ever it reads from standard input into your sed command. Maybe you intended to use something more like:

                BDUMP_DEST=`sed -e "s/[[:blank:]]//g" OUT_FILE`

Note also that the 1st line in your script:

  #!/bin/ksh

would lead people to believe that you intend to use the Korn shell to execute your script, but with the leading spaces before the #! , that line is just a comment and has absolutely no effect in determining the shell to be used to execute your code. If you are always going to invoke your script with:

sh "test.sh.bkp"

then just get rid of that line. If you always want to use sh to run your code, change the 1st line of your script to:

#!/bin/sh

(NOTE THAT THERE ARE NO LEADING SPACES ON THIS LINE) and make it executable with:

chmod +x test.sh.bkp

and execute it using:

./test.sh.bkp

(or if the directory in which you have installed this script is in your PATH variable value, just using:

test.sh.bkp

would be sufficient).

You should also get into the habit of indenting your code so that the structure of functions, conditional code, and loops are obvious. The way you indent your code obfuscates the structure of your code and makes it much harder to comprehend what it is trying to do.