Friday, March 30, 2012

Stupid Unix Tricks... Part Two (Remote Command Execution using SSH)



So, let's say that you wanted to have a script on your dbTier that will reach out to your appsTier and shut down the applications. Maybe this is your system-level shutdown script so that when the Unix administrator shuts down the dbTier, everything is shut down nice and neat like...

For the purpose of this exercise, we're going to need to assume that the APPS password is known to the script (how you do that might be the subject of another blog posting). We're also going to assume that the Unix environment is set automatically (and without prompting) on the remote system.

So, how do you do it?

Well, first you have to set up ssh pre-shared keys. This will allow you to login without being asked for a password. (See my earlier posting: Password-less Login Using SSH Pre-Shared Keys)

Once that is configured, you can use a command like this:

ssh applmgr@myappstier.mydomain "cd ${ADMIN_SCRIPTS_HOME};./adstpall.sh apps/${APPSPW}" 2>&1 |tee -a ${LOG}

A few things here. First, you'll notice that I'm actually executing TWO commands remotely. The "cd" to change directories and then the adstpall.sh script (the semicolon allows me to do that in Unix). Secondly, there are environment variables. Here's the thing about those environment variables. In the command above, they are NOT evaluated on the target system. They are evaluated locally on the SOURCE system. If you want to use variables that are local to the target, you're going to have to "escape" them.

For example, this one will use a variable evaluated on the source machine:

ssh applmgr@myappstier.mydomain "echo ${CONTEXT_NAME}"

And this one will use a variable evaluated on the target machine:

ssh applmgr@myappstier.mydomain 'echo ${CONTEXT_NAME}'

Similarly, you can evaluate a variable on the target by “escaping” it:

ssh applmgr@myappstier.mydomain "echo \${CONTEXT_NAME}"

At one client, their standard is to use a script that wraps around the standard "oraenv" to set their environment variables. As a result, every time they log in, they are greeted with a prompt asking them to choose their environment.

This raised an interesting problem for some of the automated processes we were trying to deploy. The automation was driven from a remote box and would need to ssh over to a target box and issue commands. So, how do we configure the environment so that a user logging in interactively is prompted and one issuing a command remotely through ssh isn't? Well, it turns out that, on Linux at least, that remote command doesn't get assigned a TTY. So, we've made a change to the .bash_profile on the target node that looks something like this:

if tty | fgrep pts ; then
#
# Normal, interactive logins
#
export ORAENV_ASK=YES
else
#
# Human-less logins (ssh "command")
# (Suppress output and bypass prompting for oracle environment)
#
export ORAENV_ASK=NO
fi

Now, let's assume you want to be a little more elaborate. You want to clean up extraneous output and capture the results of the command in your logfile (represented by the environment variable ${LOG}):

ssh applmgr@myappstier.mydomain ". ./.bash_profile 2>&1 1>/dev/null;cd ${ADMIN_SCRIPTS_HOME};./adstpall.sh apps/${APPSPW}" 2>&1 |tee -a ${LOG}

Or, maybe you'd like to do something in SQL*Plus on a remote system?

ssh applmgr@myappstier.mydomain “. ./.bash_profile 2>&1 1>/dev/null;sqlplus apps/${APPSPW}” <&1 1>>${LOG}
select sysdate from dual;
EOF

This will redirect stderr to stdout, and send both to your logfile (${LOG}). Pay close attention to the line containing the EOF. It has to be the ONLY thing on the line (not even a trailing space!)

James

Wednesday, March 14, 2012

OAUG Survey (part two)


As I'm reading through the OAUG survey (available here) one thing really strikes me.  If you look at Figure 30, only 24% of respondents are on E-Business Suite R12.1.  Of those that remain, 74% indicated that they are on a version of E-Business Suite that no longer covered under Premier Support.

Release Premier Extended
11.5.10.2 11/30/10 11/30/13
12.0 01/31/12 01/31/15
12.1 05/31/14 05/31/17

Remember that, for Extended Support, you will need to achieve "minimum baseline" code levels too!

More information on Oracle's Support windows in this post.

-- James

What drives E-Business Suite upgrades?



You'd think it would be new features, or security requirements. But, apparently, it's Oracle's end-of-support deadlines...


...at least according to 73% of the 327 OAUG members that responded to a survey.

UPDATE:  Here's the link to the full OAUG report:


James

Wednesday, March 7, 2012

Stupid Unix Tricks... Part 1

So, let's say you're trying to figure out if the database (or E-Business Suite) is down. Now, the logical way is use the Unix commands ps and grep to check for a particular process. Generally speaking, we would look for the SMON process for that particular instance.

However, maybe you're looking for something else that has multiple processes and you want to see that they're all shut down.

We're going to use a database as an example (largely because I assume you are familiar with the database). The basic command would be:

ps -ef|grep ora_smon_PROD
oracle 10445 6643 0 15:32 pts/0 00:00:00 grep ora_smon_PROD
oracle 19710 1 0 Feb28 ? 00:00:36 ora_smon_PROD

However, the problem here is that it also gives our grep command. To get around that, we can strip it out using grep -v grep (which would strip from our results anything that contains the string grep). Additionally, maybe we want to get something we can use in an if statement. The simplest way to do that is to count the number of lines returned by the command. That can be done by piping the output through the wc -l command. Our final command will look like this:

ps -ef|grep ora_smon_PROD|grep -v grep |wc -l

So, assuming that we just wanted to look for SMON we can build our if statement like this:

if [ `ps -ef |grep ora_smon_PROD|grep -v grep |wc -l` -gt 0 ]; then
   echo "SMON is UP"
else
   echo "SMON is DOWN"
fi

Now, let's assume that you want to check for PMON as instead:

if [ `ps -ef |grep ora_pmon_PROD|grep -v grep |wc -l` -gt 0 ]; then
   echo "PMON is UP"
else
   echo "PMON is DOWN"
fi

But what if you wanted to make sure that they were BOTH down?

if [ `ps -ef |grep -e ora_pmon_PROD -e ora_smon_PROD|grep -v grep |wc -l` -gt 0 ]; then
   echo "PMON and SMON are UP"
else
   echo "PMON and SMON are DOWN"
fi

The key here is grep -e. Because grep allows you to use the -e flag more than once per invocation, you can specify multiple strings to search for. Multiple -e strings are treated as a logical "or" by grep when it's parsing the input.

As with everything, your results may vary. Different platforms may have different versions of grep with different capabilities. This example was tested on Linux.

James