Variable fetching as null in Shell script - linux

Hi all
Iam facing an issue in the Linux shell script, TFN is fetching as NULL.
Can someone help regarding the issue will be helpful

TFN=`sqlplus -s $LOGNAME1/$PASSWORD1#connstr << EOF > ${LogFileName}
...
EOF`
Is redirecting the sqlplus output to your logfile and the command had no output (it's gone to the log file) so TFN is empty.
Remove the > ${LogFileName} to TFN gets the value of the query and then echo $FN >> ${LogFileName} if you really want the query results in the log.

Related

"Nothing in SQL buffer to run." message on executing a shell script

I am running the following shell script which calls a .SQL file, that contains a list of DELETE statements. On executing ./delete_crr_input_purge.sh, I get the following message "Nothing in SQL buffer to run.". The .SQL file gets executed anyway but what is wrong with my code in the shell script?
#!/bin/ksh
#
# #(#)Copyright All Rights Reserved.
# #(#) $Id: run_drm_utility.sh $
# Setup common environment
. `dirname $0`/db_env.sh
cd `dirname $0`
echo "Enter the SHBA Atomic DB User Name:"
read USERNAME
echo "Enter the SHBA Atomic DB User Password:"
read PASS
cnt=`sqlplus -s /nolog <<-EOF
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect $USERNAME/$PASS#$ORACLE_SID
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
#delete_crr_input_purge.sql;
commit;
EOF`
echo [$cnt]
return $?
I was able to fix this error by removing comments and occurrences of "/" from my .SQL file.
Also, I made sure that each of my SQL statements were in one line, one below the other. Also, no commit statement inside the .SQL file.

how to use /dev/null for bash command

I am using below command to get result for my SQL query.
su - postgres -c 'psql -d dbname' with stdin "COPY ( my SQL query ) TO STDOUT WITH CSV HEADER"
This works fine on my server but on different machine it is printing bash warning with output of SQL query.
For example -
/etc/profile: line 46: HISTSIZE: readonly variable
/etc/profile: line 50: HISTCONTROL: readonly variable
/etc/profile.d/20-tmout.sh: line 1: TMOUT: readonly variable
/etc/profile.d/history.sh: line 6: hcmnt_tty: readonly variable
name
abc
Please let me know anyway so that I can skip above warning messages and only get data.
If I would like to use /dev/null in this case how to modify above command to get data only.
if what you mean is "how to discard only error output?", the way to go is to redirect the standard error stream to oblivion (/dev/null), like so:
your-command 2>/dev/null
that way, if the command outputs data to standard out, it passes through, but any output to the standard error socket is discarded, so you won't see these error messages.
by the way, 2 here is a shorthand file descriptor for the standard error.
Sorry this is untested, but I hit this same error, your db session isn't read/write. You can echo the statements to psql to force a proper session as follows. I'm unsure as to how stdin may be effected
echo 'SET TRANSACTION READ WRITE; SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE ; COPY ( my SQL query ) TO STDOUT WITH CSV HEADER' | su - postgres -c 'psql -d dbname' with stdin
caution - bash hack
su - postgres -c 'psql -d dbname' with stdin "COPY ( my SQL query ) TO STDOUT WITH CSV HEADER" | grep -v "readonly"

Logging sql error from inside shell script

i am trying to implement a error logging mechanism in shell script which will also give me errors inside a sql statement
I am planning to call my script from inside another script and redirecting the error to a logfile..
is there any better option ? please help.
#!/bin/sh
./test.sh 2>&1 >> log_1.log
test.sh contains the follwing code
## testing error logging in sql
result=`sqlplus -s $username/$passwd#$db <<EOF
set serveroutout on
set pagesize 0
set heading off
set echo off
set feedback off
select first_name from employees;
exit;
EOF
if [ $? -ne 0 ]; then
echo "Error exists"
else
echo "$result"
fi
--- Edited after testing the code given by Alex Pool
I did the changes but whenever I am getting an SQL error,log file is not getting generated instead the error is being shown at the command line..
Script name -test_error_log.sh
#!/bin/sh
output=`sqlplus -s -l hr/hr#xe << EOF
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
set serveroutput on
set heading off
set pagesize 0
set echo off
select **e.firs_name --- wrong field name**
,d.department_name from
employees e , departments d
where e.department_id=d.department_id ;
exit;
EOF`
echo $output
I am calling it from caller_shell.sh in the following way
script name : caller_shell.sh
#!/bin/sh
./test_error_log.sh 2>&1 log_file
When I execute ./caller_shell.sh from command line I am getting the error a
but not at the log_file but at the screen
ERROR at line 1: ORA-00904: "E"."FIRS_NAME": invalid identifier
Please let me know how to resolve this ..
You can use whenever sqlerror to make SQL*Plus exit with an error code, which the shell script will see as the return code:
result=`sqlplus -l -s $username/$passwd#$db <<EOF
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
set serveroutput on
set pagesize 0
set heading off
set echo off
set feedback off
select first_name from employees;
exit 0;
EOF`
It will exit when the error is seen, and nothing after the point of failure will be attempted. Using failure makes it a generic failure code, but you can specify a particularly value if you prefer. But be aware of shell limits if you use your own value; in most shells anything above 255 will loop back round to zero, so it's not a good idea to try to exit with the SQL error code for example as you might get a real error that happens to end up as zero after it's been mod'ed. Using rollback means that if a failure occurs partway through a script it will roll back any (uncommitted) changes already made.
This will catch SQL errors and PL/SQL errors (unless those are caught by an exception handler and not re-raised), but won't catch SQL*Plus-specific errors - i.e. those starting SP-, such as from an invalid set command.
I've added a -l flag to the sqlplus command so it only tries to connect once, which is helpful for a non-interactive script - sometimes they can hang waiting for subsequent credentials, depending on the context and what else is in the script. I've also fixed the spelling of serveroutput and added a missing backtick...

shell script to check the sybase iq status

I am writing a script to check whether sybase is running on my server. If it is not running, i want to start the service. If it is running, i want to stop the sybase iq.
Please help me doing the same.
The logic i have written is :
if(sybaseiq = active)
then
stop_iq
else
start_iq ".cfg" ".db"
Below is the code which I found on internet.But i am not able to understand what they are doing there. Please answer me with explanation.
isql -U${USERNAME} -P${PASSWORD} -S${SQL_SERVER} -w1000 << ! > ${LOG_FILE}
exit
!
if [[ $? != 0 ]]
then
msg="`date` ${SQL_SERVER} problem. ${SQL_SERVER} on ${HOST} is down or cannot be accessed"
cat ${LOG_FILE}|/usr/bin/mailx -s "${msg}" ${SUPPORT}
}
exit 1
fi
Thanks a lot in advance
The script is fairly straight forward
First the script logs into the server via isql, redirecting the output to a log file. If it's able to connect, it issues all the commands between the exclamation points, which is an exit in this case.
Next the if statement checks the error status of the last command run $?. 0 indicates no error, anything else indicates an error. So if the error is not 0, then create a message, then send that message, along with the log file to someone.
You will have to set the values for $USERNAME, $PASSWORD, $SQL_SERVER, $LOG_FILE, $HOST and $SUPPORT somewhere in your script.
If you are not familiar with shell scripts, I would recommend you read up a bit. It's quite easy to get into, but they are quite powerful for managing *nix systems.

read command is not taking input from the terminal

I dont know if it is weird that read is not taking the input from the terminal.
The configure script, which is used in source code making process, should ask the user to give the input to select the type of Database either MYSQL or ORACLE(below is the code).
MYSQLLIBPATH="/usr/lib/mysql"
echo "Enter DataBase-Type 1-ORACLE, 2-MySQL (default MySQL):"
read in
echo $? >> /tmp/error.log
if test -z "$in" -o "$in" = "2"
then
DATABASE=-DDB_MYSQL
if true; then
MYSQL_TRUE=
MYSQL_FALSE='#'
else
MYSQL_TRUE='#'
MYSQL_FALSE=
fi
echo "Enter Mysql Library Path: (eg: $MYSQLLIBPATH (default))"
read in
echo $? >> /tmp/error.log
if test -n "$in"
then
MYSQLLIBPATH=`echo $in`
fi
echo "Mysql Lib path is $MYSQLLIBPATH"
else
if false; then
MYSQL_TRUE=
MYSQL_FALSE='#'
else
MYSQL_TRUE='#'
MYSQL_FALSE=
fi
DATABASE=-DDB_ORACLE
LD_PATH=
fi
But, the read command is not asking for the user input. Its failing to take the input from the stdin.
When I checked the status of the command in the error.log it was showing
1
1
Could anyone tell why read is failing to take the input from the stdin.
Are there any builtin variable which can block read taking the input?
Most likely read executes with standard input redirected from a file that has reached EOF. If the above is not the whole of your configure code, check that there are no input redirections. Could the code above be a part of a function which was invoked with some input from a pipe or a file? Otherwise check how configure is executed - are there any redirections?
Otherwise, the universal advice applies: try simplifying and stripping down your code until it is obvious what's happening.
BTW, it is not a good idea to make configure interactive, if you want to have your program packaged for a distribution - it's not easy to control execution of interactive programs. Consider adding support for supplying parameters through command line options.

Resources