Declare bash variables inside sql EOF - sql

how to declare variable in bash command. See "?"
I thought we could almost run any bash statement with ! or host in front of line
#!/bin/bash
sqlplus scott/tiger#orcl << EOF
! export v10="Hi" Doesn't work, why?
! echo $v10 Doesn't work, why?
! echo "Done" Works perfectly and also other bash commands
select * from dept; Works perfectly
exit
EOF
Thank you

What #jordanm says "probably" is exactly what is happening. When you specify a host command from within sqlplus, a separate shell process is spawned, the command executed by that process, then that process is terminated and control returns to sqlplus. Any environment variables that are set in that child shell process are good only within it, so when it terminates, they are gone.
As for your specific lines that "work" and "don't work" .. "export v10="Hi" does work but there is no stdout display of the 'export' command, and as explained, that variable v10 ceases to exist once the child process completes and control returns to sqlplus. The "echo $v10" also works, but since that is a new shell process, it has no value for $v10, so there is nothing to echo.
What are you trying to accomplish by setting enviornment variables from within sqlplus?

found it, all I had to do was
<< EOF
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
#scriptname.sql
EXIT
EOF

Related

Check stored procedure in shell script

I want to know how to write a shell script that access oracle database and check a procedure that executed earlier if it is succeeded or returned error
If you want to know about procedure that executed earlier (in a different session?), you can't, unless the results were persisted somehow. Oracle by itself doesn't store info about every procedure call.
If you just want to run and check the stored procedure immediately from the shell script, that's a standard pattern, use whenever sqlerror/oserror clause:
sqlplus [connection_string] <<-EOF
whenever oserror exit failure;
whenever sqlerror exit failure;
exec [stored_procedure];
EOF
if [[ $? != 0 ]]; then
echo "Procedure failed!"
exit 1
fi
->Reference

How do I nohup a here document in the background from within a ksh script?

I have a ksh script that comes to a point where it must run a long running command. The long running command is executed via a heredoc in the script presently. I want to throw the command (represented by cat in my samples below) into the background but only after taking its input from the heredoc. Since the "nohup cat.." finishes instantaneously and I see an empty nohup.out file, I am not sure the script is doing what I need it to do, which is to spawn a nohupped version of the heredoc command and exit, leaving the command to run for however long it takes to complete.
I am using cat as the "command" since it too sits there and just waits for console input.
Working version without nohupping:
#!/bin/ksh
cat << EOF
Hello
World
HOw are you!
EOF
Trying to nohup the heredoc:
#!/bin/ksh
nohup cat <<EOF
Hello
World
HOw are you!
EOF
Seems to work, output is going into nohup.out as expected. But now, how to throw that into the background? I tried the below (and many variations of it) :
#!/bin/ksh
nohup cat & <<EOF
Hello
World
HOw are you!
EOF
but, nohup.out is empty, so I am not sure what the above is doing. There is no running "cat" in the background which tells me it ran and completed at least - or maybe didn't run at all. No other variation I can invent for trying to throw the heredoc into the background from my ksh script works.
Any suggestions on a way to achieve this using heredoc?
Here are two options.
You could try wrapping the nohup sequence inside a function, which may look cleaner, and then invoking that function with the trailing ampersand.
Using a function, like this:
#!/bin/ksh
function dostuff
{
nohup cat <<- END
Hello
World
How are you!
END
}
dostuff &
wait
You can also try wrapping the commands to be backgrounded into a grouping { } block, separating each command with a ; inside the brackets, and then backgrounding that block via:
{ nohup cat <<- EOF
...
EOF
; whatever
} &

how to see if a process by name is running in tcl

I want to use the pidof by a process given by name in tcl. I have used [exec pidof $proc_name ], but it always returns an error: child process exited abnormally.
I read somewhere exec always treat non-zero return as error as pidof return the process id number. Does anyone know if there is a workaround? Thanks in advance!
I want to use pidof is that i want to see if that process is running if not i will restart the process.
The problem is that pidof does strange things with exit codes:
Exit Status
At least one program was found with the requested name.
No program was found with the requested name.
This interacts badly with exec which treats a non-zero exit code as indicating that it should tell the rest of Tcl that there was an error.
The simplest way of dealing with this is a little extra shell script wrapper. Let's hide it inside a procedure for convenience:
proc pidof {name} {
exec /bin/bash -c "pidof '$name'; exit \$(( \$? - 1 ))"
}
All that does is subtract 1 from the exit code before it hits back into Tcl.
(You could also fix this using the techniques described in the exec manual but I think it's simpler to fix on the bash side this time.)
I ran into this and ended up causing some issues with the old linux environment I run in (no bash and exit code handling was a bit different with busybox).
My solution that should work anywhere would be similar to what a few suggested:
proc pidof {name} {
catch {exec -ignorestderr -- pidof $name} pid
if {[string is entier -strict $pid]} {
return $pid
}
}

Sqlplus parameters

everyone!
I want to know what this line does:
sqlplus -s /nolog <<EOF
Any ideas?
Thanks for the help!
From the information that you provided in the comments:
sqlplus -s /nolog <<EOF
Fires up an instance of sqlplus with silent mode enabled (which, I believe, doesn't send out any output to the console screen), and without a login explicitly provided (hence the /nolog), and it's taking input from the string contained in the EOF heredoc (which probably contains login credentials).
Here is a quick overview of Oracle's documentation on sqlplus.
From HERE:
-s The silent option: it suppreses the output of the SQL*Plus banner, the command prompt and the echoing of commands.
/nolog Starts SQL*Plus but does not log on (connect) a user/session.
So it seems that starts SQL*PLUS without logging on a user/session (nolog option) and don't display info (silent option).
The full excerpt should probably be:
sqlplus -s /nolog << ABCDE
CONNECT user/pwd#database
-- DO SQL AND PLSQL STUFF
EXIT
ABCDE
Which is similar to running sqlplus -s user/pwd#database #script.sql where script.sql contains the sql, plsql stuff and the exit command. The << syntax is shell operator for heredoc, which means all following lines are variable-expanded if ${variables} are found, and the first line beginning with ABCDE (at the very beginning of the line, no spaces, no tabs) ends the input.

Expect script does not work under crontab

I have an expect script which I need to run every 3 mins on my management node to collect tx/rx values for each port attached to DCX Brocade SAN Switch using the command #portperfshow#
Each time I try to use crontab to execute the script every 3 mins, the script does not work!
My expect script starts with #!/usr/bin/expect -f and I am calling the script using the following syntax under cron:
3 * * * * /usr/bin/expect -f /root/portsperfDCX1/collect-all.exp sanswitchhostname
However, when I execute the script (not under cron) it works as expected:
root# ./collect-all.exp sanswitchhostname
works just fine.
Please Please can someone help! Thanks.
The script collect-all.exp is:
#!/usr/bin/expect -f
#Time and Date
set day [timestamp -format %d%m%y]
set time [timestamp -format %H%M]
#logging
set LogDir1 "/FPerf/PortsLogs"
et timeout 5
set ipaddr [lrange $argv 0 0]
set passw "XXXXXXX"
if { $ipaddr == "" } {
puts "Usage: <script.exp> <ip address>\n"
exit 1
}
spawn ssh admin#$ipaddr
expect -re "password"
send "$passw\r"
expect -re "admin"
log_file "$LogDir1/$day-portsperfshow-$time"
send "portperfshow -tx -rx -t 10\r"
expect timeout "\n"
send \003
log_file
send -- "exit\r"
close
I had the same issue, except that my script was ending with
interact
Finally I got it working by replacing it with these two lines:
expect eof
exit
Changing interact to expect eof worked for me!
Needed to remove the exit part, because I had more statements in the bash script after the expect line (calling expect inside a bash script).
There are two key differences between a program that is run normally from a shell and a program that is run from cron:
Cron does not populate (many) environment variables. Notably absent are TERM, SHELL and HOME, but that's just a small proportion of the long list that will be not defined.
Cron does not set up a current terminal, so /dev/tty doesn't resolve to anything. (Note, programs spawned by Expect will have a current terminal.)
With high probability, any difficulties will come from these, especially the first. To fix, you need to save all your environment variables in an interactive session and use these in your expect script to repopulate the environment. The easiest way is to use this little expect script:
unset -nocomplain ::env(SSH_AUTH_SOCK) ;# This one is session-bound anyway
puts [list array set ::env [array get ::env]]
That will write out a single very long line which you want to put near the top of your script (or at least before the first spawn). Then see if that works.
Jobs run by cron are not considered login shells, and thus don't source your .bashrc, .bash_profile, etc.
If you want that behavior, you need to add it explicitly to the crontab entry like so:
$ crontab -l
0 13 * * * bash -c '. .bash_profile; etc ...'
$