escaping variable in shell script - bash

I have script below i am using get value of one parameter
var=`ssh -X -o StrictHostKeyChecking=no $phost "
cd ; . ./.bash_profile;cd $ORACLE_HOME/dbs; sqlplus -s / as sysdba <<EOF
set heading off
set pagesize 0
set tab off
set feedback off
select value from v$parameter where name='control_files';
EOF
"`
this script this fetching value from table v$parameter and assigning it to variable var, now how can i escape $ from v$parameter
i have tried v\$parameter but it didnt help

You can cat the code lines into a file during the script run and then run the created script.
Something like:
echo "set heading off" > tempfile.sh
echo "set pagesize 0" >> tempfile.sh
echo "set tab off" >> tempfile.sh
echo "set feedback off" >> tempfile.sh
echo "select value from v${parameter} where name='control_files';" >> tempfile.sh
chmod +x tempfile.sh
./tempfile.sh

Related

What is the correct way of quoting named arguments in bash?

In bash I can use named arguments like this:
command --argument=value
What is the correct way of quoting them if I need to include spaces?
command --argument="long value"
or
command "--argument=long value"
What is the correct way of quoting them if I need to include spaces?
Any quoting that does the job - preserves the space that you want to preserve - is fine. Any of these run the same command:
echo cmd --argument="long value"
echo cmd "--argument=long value"
echo cmd --argument=long\ value
echo cmd --argument=long' 'value
echo cmd --argument=long" "value
echo cmd --argument=long" value"
echo cmd --argument=l'ong 'value
echo cmd '--argument=long value'
echo cmd '''--argument=long value''' # same as above, with empty '' pairs
echo cmd '-'-'a'r'g'u'm'e'n't'='l'o'n'g v'a'l'u'e' # just having fun
You can check if your quoting is fine with set -x and inspecting the output.
$ set -x
$ echo cmd --argument="long value"
+ echo cmd '--argument=long value'
$ echo cmd "--argument=long value"
+ echo cmd '--argument=long value'

Is there an way to preserve the sqlplus connection from shell script

In DB2, after connecting to DB, until and unless we are specifically use TERMINATE command, the connection keeps open and can be used for several sql execution using same connection inside a shell script.
Is there any way to do the same in oracle sqlplus from shell script?
For Example: bash script may look like below
1. start of bash
2. sqlplus connection created
3. some bash commands
4. execute query using the same sqlplus connection created in 2nd step
5. some bash commands
6. execute query using the same sqlplus connection created in 2nd step
thanks for the help. I have found another solution which I think best suits my requirement and its working perfectly fine.
By accessing SQL*Plus using a Korn Shell Coprocess.
Below is an example I have run and it has given all results perfectly.
#!/bin/ksh
##
##
output=""
set -f output
integer rc
typeset -r ERRFILE=$0.err
typeset -r EOF="DONE"
## Create the error file or zero it out if it already exists.
> $ERRFILE
## Start sqlplus in a coprocess.
sqlplus -s connection |&
## Exit SQL/Plus if any of the following signals are received:
## 0=normal exit, 2=interrupt, 3=quit, 9=kill, 15=termination
trap 'print -p "exit"' 0 2 3 9 15
## Send commands to SQL/Plus.
print -p "set heading off;"
print -p "set feedback off;"
print -p "set pagesize 0;"
print -p "set linesize 500;"
##
## Send a query to SQL/Plus. It is formatted so we can set a shell variable.
##
print -p "select 'COUNT1='||count(*) as count from dual;"
print -p "prompt $EOF"
while read -p output
do
if [[ "$output" == "$EOF" ]]; then
break
else
## eval forces the shell to evaluate the line twice. First, replacing
## "$output" with "COUNT1=99999", then again which creates and sets
## a variable.
eval $output
fi
done
##
## Send another query to the same running sql/plus coprocess.
##
print -p "select 'COUNT1_DATE='|| sysdate as count_date from dual;"
print -p "prompt $EOF"
while read -p output
do
if [[ "$output" == "$EOF" ]]; then
break
else
eval $output
fi
done
print -p "select 'COUNT2='||count(*)||';COUNT2_DATE='||sysdate from dual;"
print -p "prompt $EOF"
while read -p output
do
if [[ "$output" == "$EOF" ]]; then
break
else
eval $output
fi
done
print -p "select count(*)||'|'||sysdate from dual;"
print -p "prompt $EOF"
while read -p output
do
if [[ "$output" == "$EOF" ]]; then
break
else
IFS="|" ## Set the Input Field Separator.
set -A output_array $output ## Create an array. It parses
## automatically on the IFS character.
fi
done
print "COUNT1 count is $COUNT1"
print "COUNT1 date is $COUNT1_DATE\n"
print "COUNT2 count is $COUNT2"
print "COUNT2 date is $COUNT2_DATE\n"
print "Array count3: ${output_array[0]}"
print "Array date3: ${output_array[1]}"

configuring fish shell prompt inside nix-shell

I tried following the steps here to configure the prompt: https://nixos.wiki/wiki/Fish
Combined with the information here about the location and content of a basic file: https://fishshell.com/docs/current/faq.html#how-do-i-set-my-prompt
If I understood correctly the content of fish_prompt.fish should be:
set -l nix_shell_info (
if test -n "$IN_NIX_SHELL"
echo -n "<nix-shell> "
end
)
function fish_prompt
set_color $fish_color_cwd
echo -n (prompt_pwd)
set_color normal
echo -n -s ' $nix_shell_info ~>'
end
After setting it this way the prompt is the same whether in a nix-shell or not and the variable $nix_shell_info does not get set.
How can I set it so that it works as intended?
You need to set the variable inside the function, otherwise it would always contain the value set when the file was loaded:
function fish_prompt
set -l nix_shell_info (
if test -n "$IN_NIX_SHELL"
echo -n "<nix-shell> "
end
)
set_color $fish_color_cwd
echo -n (prompt_pwd)
set_color normal
echo -n -s " $nix_shell_info ~>"
end
Edit: As cole-h pointed out on IRC, you also need to also change the single quotes containing the variable to double quotes or it will not be interpolated.

Unable to print user input after executing the script by opening the gnome-terminal

I am trying to make the script which executes on terminal on double click and should ask for user input. To execute script open the gnome-terminal which will execute further script. After taking user input in RESP it unable to print the value passed(y/n). Gnome-terminal with nautilus.
gnome-terminal -- bash -c "read -p 'Include log?(y/n)' RESP
echo '$RESP'
if[ '$RESP' = 'y' ]; then
//logic for yes
else
//logic for no
fi;
exec bash"
echo $RESP not printing anything?
Try this
bash -c "read -p 'Include log?(y/n)' RESP
echo \$RESP
if [ \$RESP = 'y' ]; then
echo y
else
echo n
fi"
You need to escape the $ for your variables instead of putting it into '
The " in script string made variable empty (not defined variable expands to nothing) . It makes echo empty. I exchanged " with ' and it works fine.
gnome-terminal -- bash -c 'read -p "Include log?(y/n)" RESP
echo "$RESP"; sleep 10
if[ "$RESP" = "y" ]; then
echo YES
else
echo NO
fi;
exec bash'

Return value from sql script to shell script

I have shell script that calls the following sql script:
INSERT INTO SEMANTIC.COUNT_STATISTICS (...);
UPDATE SEMANTIC.COUNT_STATISTICS
SET PRNCT_CHANGE = 1.1;
--want to store result of this bellow select statement in model_count variable
select PRNCT_CHANGE
FROM SEMANTIC.COUNT_STATISTICS
WHERE model = '&MY_MODEL'
AND NEW_DATE = (
select max(NEW_DATE)
from SEMANTIC.COUNT_STATISTICS
where MODEL = '&MY_MODEL'
);
Now, how do I return this PERCENTAGE_NUMBER variable back to my shell script?
My shell script is as follows:
#!/bin/bash
#
# setup oracle, java, and d2rq environment
. /etc/profile.d/oracle.sh
. /etc/profile.d/java.sh
. /etc/profile.d/d2rq.sh
cd /opt/D2RQ
model_count=$(sqlplus user/pass #count.sql 'MODEL')
if ["$model_count" > 0]; then
echo "percentage count is positive"
else
echo "its negative"
I would like for that last SELECT statement result to be stored into my model_count variable in shell script.
Anyone knows why is not working?
A bash example with the use of a bash-function (note! database OS-authentication "/")
#!/bin/bash
get_count () {
sqlplus -s / <<!
set heading off
set feedback off
set pages 0
select count(*) from all_objects where object_type = '$1';
!
}
count=$(get_count $1)
echo $count
if [ "$count" -gt 0 ]; then
echo "is greater than zero"
else
echo "is less or equal to zero"
fi
~/tmp/ $ ./count.sh INDEX
2922
is greater than zero
~/tmp/ $ ./count.sh TABLE
1911
is greater than zero
~/tmp/ $ ./count.sh FUNCTION
226
is greater than zero
~/tmp/ $ ./count.sh "SUPEROBJECT"
0
is less or equal to zero
What I actually did is I separated those 2 queires and called them separatelly in my shell script:
sqlplus -S user/pass << EOF
whenever sqlerror exit 1;
set echo on
#/opt/D2RQ/model_count.sql '$MODEL' <--model_count.sql still has those INSERT & UPDATE statements
exit;
EOF
model_count=`sqlplus -S user/pass << EOF
SELECT PRNCT_CHANGE
FROM COUNT_STATISTICS
WHERE model = '$MODEL'
AND NEW_DATE = (
select max(NEW_DATE)
from COUNT_STATISTICS
where MODEL = '$MODEL'
);
exit;
EOF`
if [ $model_count >= 0 ]; then
echo "$model_count"
else
echo "'$MODEL' is negative " | mail -s "scripts issues" -c angelina1984#aol.com
fi

Resources