Executing script variable by variable - shell

i have a script & it goes as below,
instant_client="/root/ora_client/instantclient_11_2"
output=`$instant_client/sqlplus -s HRUSER/HRUSER#TOMLWF <<EOF
set heading off
set feedback off
set lines 10000
set pagesize 10000
select count (1) from onboardingcandidates o, candidatedetails c where o.candidateid=c.candidateid and o.JOININGSTATUS='0091' and to_date(o.joiningdate)=to_date(sysdate+5);
EOF
exit
`
query=(`$instant_client/sqlplus -s HRUSER/HRUSER#TOMLWF <<EOF
set heading off
set feedback off
set lines 10000
set pagesize 10000
select o.candidateid from onboardingcandidates o, candidatedetails c where o.candidateid=c.candidateid and o.JOININGSTATUS='0091' and to_date(o.joiningdate)=to_date(sysdate+5);
EOF`)
i=0
echo "Throwing individual arrays:"
while [ $i -lt $output ]
do
a=${query[$i]}
echo Candidate[$i]=$a
i=$(($i+1))
done
OUTPUT:
Throwing individual arrays:
Candidate[0]=cand1
Candidate[1]=cand2
Candidate[2]=cand3
Candidate[3]=cand62
REQUIRED OUTPUT
Everything is working fine.
All i need is, i need 1 output at a time.
i.e. if i run the above script then the output should be controlled.
It should throw 1 output at a time on the prompt.
Is this possible ??
IF YOU NEED ANYTHING MORE THEN PLZ ASK. I HOPE I AM CLEAR WITH MY DOUBT

So you're running two queries, one to get the count of the number of results, the second to get the results.
If you want to only have one query, you can iterate through the count of the number of results. as the variable query is an array, you can use:
${#query[*]}
as the number of result rows, then use:
while [ $i -lt ${#query[*]} ]
as the loop condition.
If you want to display one result at a time, and require an enter between them, then you can add a read after the echo.
If you want to display a specific return row, then, assuming that the routine is called as-is, then the row number to display is passed in as the first parameter $1, then you can use:
a=${query[$1]}
echo Candidate[$1]=$a
if you just want to display the result at that line, without the Candidate[] text, then you can just echo:
echo ${query[$1]}

If I have understood your question correctly, before your echo statement to print the output,put this line:
read dummy
This will prompt you to enter some key, when entered, will show the next line output.

Related

Strange Behavior in Bash For Loop

Given the following code, BASH's output is unexpected for me and I'm looking for possible solutions (I've tried changing the way I'm quoting but that doesn't seem to affect anything to produce the desired result):
Testing File:
#!/bin/bash
. FindMissingSettings.function
Settings[0]="FirstSetting"
Settings[1]="SecondSetting"
Settings[2]="ThirdSetting"
ThisFile="ThisFile"
find_missing_settings "${Settings[#]}" "$ThisFile"
The included FindMissingSettings.function:
#!/bin/bash
find_missing_settings () {
Settings=("$#")
File=$2
for Setting in "${Settings[#]}"; do
echo "$Setting"
echo "1"
done
echo "$File"
echo "2"
}
I expected the output from this script and the included function to be:
FirstSetting
1
SecondSetting
1
ThirdSetting
1
ThisFile
2
However this was the result I received:
FirstSetting
1
SecondSetting
1
ThirdSetting
1
ThisFile
1
SecondSetting
2
Why is this and what can I do to provide the desired result? Thank you!
In your find_missing_settings function, in your variable Setting, you have all the given inputs (FirstSetting, Second Setting, ThirdSetting, ThisFile). That's why it print it all with during the loop.
Then it print the 2nd setting in the list, so SecondSetting
To fix this, you can put ThisFile as first parameter of the function:
find_missing_settings "$ThisFile" "${Settings[#]}"
And change in the find_missing_settings function how you get the inputs:
Settings=("${#:2}")
File=$1
The :2 ask to get the inputs starting from the 2nd one only, and you put the first one (ThisFile) in the variable File

Have unique values in each while loop iteration

What I try to achieve, is to define global variables in my script. These variables can be reused in a loop (preferably a while loop..) and with every iteration, the loop should get a new set a variables.
My script (so far):
PACKAGE_ASSET_ID=AUTO`date +%s`000001
TITLE_ASSET_ID=AUTO`date +%s`000002
MOVIE_ASSET_ID=AUTO`date +%s`000003
PREVIEW_ASSET_ID=AUTO`date +%s`000004
POSTER_ASSET_ID=AUTO`date +%s`000005
while read name; do
#DATE=`date +%s`
#PACKAGE_ASSET_ID="AUTO${DATE}000001"
#TITLE_ASSET_ID="AUTO${DATE}000002"
#MOVIE_ASSET_ID="AUTO${DATE}000003"
#PREVIEW_ASSET_ID="AUTO${DATE}000004"
#POSTER_ASSET_ID="AUTO${DATE}000005"
echo $PACKAGE_ASSET_ID
echo $TITLE_ASSET_ID
echo $MOVIE_ASSET_ID
echo $PREVIEW_ASSET_ID
echo $POSTER_ASSET_ID
done <names.txt
Within the file names.txt, there are 15 entries. For every entry, the while loop needs to process these sets of variables. Giving me something like
AUTO1521884581000001
AUTO1521884581000002
AUTO1521884581000003
AUTO1521884581000004
AUTO1521884581000005
AUTO1521884592000001
AUTO1521884592000002
AUTO1521884592000003
AUTO1521884592000004
AUTO1521884592000005
As you can see in the script, I tried putting it into the while loop and with different syntax but regretfully, without success. The results I get are always the same set of variables, for all the 15 entries.
Did you really expect that bash (even bash!) would need more than a second to read one line?? Try adding the nanoseconds.
while read name; do
DATE=$(date +%s%N)
PACKAGE_ASSET_ID="AUTO${DATE}000001"
TITLE_ASSET_ID="AUTO${DATE}000002"
MOVIE_ASSET_ID="AUTO${DATE}000003"
PREVIEW_ASSET_ID="AUTO${DATE}000004"
POSTER_ASSET_ID="AUTO${DATE}000005"
echo $PACKAGE_ASSET_ID
echo $TITLE_ASSET_ID
echo $MOVIE_ASSET_ID
echo $PREVIEW_ASSET_ID
echo $POSTER_ASSET_ID
done <names.txt

Comparing result, input and output of tests in shell

Basically what I want to do is write a shellscript that will run series of test, take in any input (if there is any) and compare the test result with an output.
So my file looks something like this.
#!/bin/sh
# Let's set our working directory
DIR="./tests"
# And create some variables
passed=0
failed=0
totalamount=0
returned=0
# Inform the user about start of testing
echo "========= TESTING INITIALIZED ========="
# Actual testing I'm trying to do
So I assume first thing I should do is create a loop that will run through the tests
for file in "./tests/1/*.test do
So Now I'm unsure how can I compare the output of my .test file with a prepared .output program.
For example, I have a program test1.test, that will calculate 2+3. The result is 5. What I want is to have this value stored and compare it with my test1.output
Any idea how to do this?
In the end I'll just compare the two values
if [ $returned -eq $expected ]; then
echo "Test was succesful"
else
echo "Test was unsuccesful"
fi
Basically the end result should look something like:
Test: test1.test
Expected result: X
Your result: Y
Test was succesful/unsuccesful
You could use diff to compare the test result with the output expected. If they match, then you could assume the test was successful. For example:
test1check="$(diff /folder/test1 /folder/test1-expected)"
if [ -z "$test1check" ]; then
echo "Test was succesful"
else
echo "Test was unsuccesful, difference on results: $test1check"
fi
If the user is going to make inputs, or in other cases at your discretion, you could run the same comparison but ignore case differences (ex: "APPLE" would match "apple"), by changing the first line like this:
test1check="$(diff -i /folder/test1 /folder/test1-expected)"
One more thing: keep in mind that this code is sensitive to newlines, so if the test result does not end in a new line and the expected result does, the script will point out the difference.

Ksh function to query Oracle with return values

Some time ago I wrote a small routine to run some quick n' dirty queries (and with that I mean it is not used for large queries) against an Oracle DB, but also wanted to do it a bit easier to parse errors. Follows:
# Executes the query
#
# Will execute a query contained in the variable named
# in the parameter $4 and store the result in the variable
# named in $5.
# In case of errors (even SQL related) the function should
# exit with status 1, making it possible to "if execQuery".
#
# #param $1 = User
# $2 = Pasword
# $3 = Tns Alias
# $4 = Name of the variable containing the query
# $5 = Name of the variable to hold the result
#
# #return query execution status
function execQuery {
typeset eSQLU=$1
typeset eSQLP=$2
typeset eSQLS=$3
typeset etQUERY=$4
eval typeset eQUERY=\$$etQUERY
typeset eQRES=$5
logMessageFile "DEBUG" "Query: $eQUERY"
typeset res=$(sqlplus -s $eSQLU/$eSQLP#$eSQLS <<EOF
set echo off newpage 0 space 0 pagesize 0 feed off head off verify off lines 999
WHENEVER SQLERROR EXIT 1
$eQUERY
exit;
EOF
)
[[ $? -gt 0 ]] && return 1 || eval "$eQRES=\"$res\""
}
The idea of this function is that later I could do something like:
query="select sysdate from dual;"
if execQuery $RAID_APP_PI_USR $RAID_APP_PI_PWD $RAID_APP_PI_SID query result ; then
echo $result
logMessageFile "INFO" "Inserts into XX successful."
else
logMessageFile "ERROR" "Error insertando XXX."
fi
It kinda works... A properly written query will do it fine, and the result variable is all correctly evaluated and all. The problem are the errors. If the query in that example was something like select * potato potato;, It'd still not yield the correct return value thus missing the error test.
I'm not particularly good with sqlplus nor ksh, probably just missing something obvious... Could someone lend me a hand here?
Thanks!
I believe $? is returning the exit status of the typeset command, not the sqlplus command.
It may be easier to output the results of your SQLPLUS statement to a file instead of into a variable. Then you could either read that file with grep, looking for an "ORA-" message, or check the exit status variable.
sqlplus -s $eSQLU/$eSQLP#$eSQLS > querylog.tmp <<EOF
set echo off newpage 0 space 0 pagesize 0 feed off head off verify off lines 999
WHENEVER SQLERROR EXIT 1
$eQUERY
exit;
EOF
echo $?

how to remove space in echo?

s#!/bin/ksh
usrid=`sql_login.sh`
if [ "$?" -ne "0" ]; then
echo "sql login failed-Username/Password not available in control file"
exit -1
fi
a=`sqlplus -s ${usrid} <<EOF
set pause off
set heading off
set feedback off
set serveroutput off;
select 10 from dual;
exit;
EOF`
b=`sqlplus -s ${usrid} <<EOF
set pause off
set heading off
set feedback off
select 11 from dual;
exit;
EOF`
echo "Out of sqlplus session";
echo $a$b;
hi its giving output like 10 11? i need it 1011 how can i achive this?
solution:
a1=$(echo ${a#}) ;
b1=$(echo ${b#}) ;
c1=$a1$b1;
echo $c1;
There must be spaces included in the value of a (and probably b too)
You can get rid of the space by modify the value of the variable.
assuming you have bash, ksh or other POSIX shell
echo ${a% }${b% }
will probably work.
${var% } says, for ${var} remove from the left of the variable's value a space char (if there is one there.
If for some reason, you find that the space is in the front, like ' a', then use
${a# }, which means remove from the right of the variable's value a space char.
EDIT : kurumi's solution (assuming bash and POSIX shell is probably better)
because then it doesn't matter where in the line that space value occurs.
BUT why don't you concatenate the two values and have just 1 sql query?
$ab=...
select 10 + 11 from dual;
You may have to consult with you oracle friends to get this exactly right, but in the SQL Sybase DB (and probably MS SQL), this wouldn't be a problem.d
ALSO, Stop using backquotes, they are deprecate since 1992 (at least)
ab=$( cmd ) is so much nicer ;-)
I hope this helps.
P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, or give it a + (or -) as a useful answer
you can try
c="$a$b"
echo ${c// }
or remove spaces at each individual variables themselves
a=${a// }
b=${b// }
or you can call externals
echo $a | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//'

Resources