unix oracle shell scripting

Upload: lado55

Post on 14-Apr-2018

278 views

Category:

Documents


2 download

TRANSCRIPT

  • 7/30/2019 Unix Oracle Shell Scripting

    1/22

    UNIX SHELL SCRIPTINGIN AN ORACLE ENVIRONMENT

    By

    William A. Ducat

    Ambassador, Inc.

    5299 DTC Boulevard

    Suite 290Englewood, CO 80112(888) 775-3778 x227 (Voice)(630) 839-5264 (Fax)

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    2/22

    UNIX Shell Scripting for Oracle Ducat

    Table of ContentsIntroduction................................................................................................................................................. 3

    Conventions ............................................................................................................................................ 3Building Blocks .......................................................................................................................................... 4

    Concepts.................................................................................................................................................. 4STDOUT............................................................................................................................................. 4STDERR ............................................................................................................................................. 4STDIN ................................................................................................................................................. 5Environment Variables ....................................................................................................................... 6Scripts.................................................................................................................................................. 6Parameter Passing ............................................................................................................................... 8Flow Control ....................................................................................................................................... 9Identifying your process.................................................................................................................... 10

    Practical Examples.................................................................................................................................... 11Password Management ......................................................................................................................... 11Embedded SQL..................................................................................................................................... 12Embedded Subroutines (aka Functions) ............................................................................................... 13Passing Parameters................................................................................................................................ 15Global Functions ................................................................................................................................... 18

    Conclusion ................................................................................................................................................ 22Sample Code

    Figure 1 - Redirecting STDERR to a file.................................................................................................... 4Figure 2 - Redirecting STDERR to STDOUT............................................................................................ 4Figure 3 - Redirecting STDIN in a script.................................................................................................... 5Figure 4 - Basic script ................................................................................................................................. 7Figure 5 Sample setup_passwords.ksh script......................................................................................... 11Figure 6 - PS results on HP or Sun ........................................................................................................... 12Figure 7 - PS results on Compaq or Linux ............................................................................................... 12Figure 8 - Embedding SQL in a KSH script ............................................................................................. 13Figure 9 - Implementing a user-defined function in a KSH script ........................................................... 14

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    3/22

    UNIX Shell Scripting for Oracle Ducat

    IntroductionThe primary purpose of this paper is to provide a starting point for your own scripting projects. To accomplish this, the paper

    is divided into two major sections. The Building Blocks section will describe some of the required basic concepts, and thePractical Examples section takes these basic constructs and steps through the construction of a rather useful script. Thescript starts out as a very basic script , and by applying multiple new features, becomes a very flexible and useful tool.

    Developing scripts for the Oracle environment involves performing some rather complex tasks, and the KORN shell naturallylends itself to the task. Because of this, and its wide availability, we will use the KORN shell for all examples.

    In the UNIX environment, a users interactive environment or scripts always run in some sort of shell. A shell can be thought

    of as an interface to the underlying UNIX command set. Most tasks can be completed in any available shell, but each shellhas various attributes, which tend to make it desirable for various applications. For instance, the Bourne shell (/bin/sh) is avery basic shell, which is common to most UNIX installations. Many install programs use the BOURNE shell since one

    script can be used, unchanged, on multiple platforms. The C shell (/bin/csh) has various features to assist in the interactiveenvironment, and many users make the C shell their default 1 shell for this reason. The KORN shell (/bin/ksh) lends its self toheavy scripting, and includes the ability to define functions that are local to a script, as well as functions that are available to

    the users interactive session. Another relative newcomer in the shell arena is the BASH shell (/bin/bash)(a.k.a Bourne AgainShell). BASH attempts to combine the best of the C and BOURNE shells into one. BASH is not widely used at this time, buthas the potential to become very popular.

    ConventionsIn this paper when a space is critical, the b symb ol will be used to denote each space.

    When something is enclosed in a box, as is this paragraph, it contains commands toenter, the text of a UNIX script, or the results of a script or command.

    1 The default shell for a user is specified on the users entry in the /etc/passwd file.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    4/22

    UNIX Shell Scripting for Oracle Ducat

    Building BlocksUNIX can be thought of as a very thin operating system. Instead of providing a series of very powerful commands with

    numerous options, such as the VMS operating system, it provides a large number of very simple commands which can bestrung together to obtain the desired result. A simple script is nothing more than a series of commands or strings ofcommands executed in a sequential manner. A complex script uses flow control constructs and conditional operators to

    control the execution of commands much like a 3GL such as C, BASIC or Fortran.

    ConceptsNumerous texts cover the syntax and purpose of all of the UNIX commands, and we will not attempt to cover all of themhere. We will however cover some of the more useful ones from a scripting standpoint, as well as some basic issues related toall commands.

    There are three things common to most commands. First, they need a source of input. Second, they need somewhere to sendtheir output. Third, they need somewhere to send the results of any errors encountered. In the UNIX world, we havestandard input (STDIN), standard output (STDOUT), and standard error (STDERR). The default values for each

    command differ, but as a rule, STDOUT and STDERR are sent to the screen, and STDIN will be requested interactively fromthe user, or from a file.

    STDOUT

    When performing a command such as ls, the results of the listing are displayed to the screen. This can be changed byredirecting STDOUT with the > redirector. For instance, if the ls >listing.out command is issued, the file listing.outwill be created if it does not exist, or it will be replaced if it does exist. When complete, the file will contain the results of the

    ls command. When the > is used, the results will not be shown on the screen. The >> redirector works like > exceptit will append the to a file if it already exists.

    STDERR

    If an ls command returns no files found, the resulting error message is shown on the screen. If the same command isperformed except the results are redirected to a file, the resulting file will be empty and the error message will still bedisplayed on the screen. The reason is that the results are being sent to STDOUT, and the error is sent to STDERR. Take the

    following command as an example:

    ls myfile* >results.txt 2>errors.txt

    Figure 1 - Redirecting STDERR to a file

    STDERR is referenced via the 2> redirector. In this case, results are sent to the results.txt file, and errors are sent to the

    errors.txt file. In a given command, STDOUT can be referenced as &1. Consider the following command:

    ls myfile* >results.txt 2>&1

    Figure 2 - Redirecting STDERR to STDOUT

    In this case, the results.txt file will contain both the results and the errors (if any), since STDERR is redirected to STDOUT.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    5/22

    UNIX Shell Scripting for Oracle Ducat

    STDINStandard input typically comes from one of three sources. The first is interactively from the keyboard, the second is from an

    input file, and the third is from the output of another command. When writing a script to be run in batch mode, keyboardentry is usually not an option. For instance, if a script is require to enter Sql*Plus and execute an update statement, how can itbe done? One possibility would be to add an @ command to the startup of Sql*Plus, but maybe a single file is desired.

    One answer is to have Sql*Plus take its input from the script instead of the keyboard. Redirecting STDIN can do this.

    sqlplus scott/tiger s Figure 3 - Redirecting STDIN in a script

    In this example, the

  • 7/30/2019 Unix Oracle Shell Scripting

    6/22

    UNIX Shell Scripting for Oracle Ducat

    Tinkertoys. They can be put them together in many ways to solve the same problem, and there is no one correct answer.The best we can hope to accomplish here is to show various contraptions others have built, and turn your imagination loose to

    invent your own!

    Environment VariablesEnvironment variables behave much like variables in any language except they are available throughout the shell

    environment. There are two basic ways to view the contents of an environment variable. First, the UNIX command envwill show all variables, and the echo command can be used to display a single variable. When referencing an individualvariable, the variable name must be referenced starting with the $ character, and optionally, the variable name can be

    enclosed in {} characters. For instance, to display the contents of the ORACLE_SID variable, either of the followingcommands could be used:

    echo $ORACLE_SID

    echo ${ORACLE_SID}

    While both commands will work, the second method is desirable. The basic reason is consistency. Good programming

    techniques dictate a consistent style, and the first method does not always work. For instance, lets assume a script mustdisplay the contents of the ORACLE_SID variable followed by _world.

    echo $ORACLE_SID_worldecho ${OACLE_SID}_world

    The second example would give the desired result, but the first would be looking for a variable named ORACLE_SID_world.

    NOTE: Keep in mind that variable names, like most things in UNIX, are case sensitive.

    One use of environment variables is to store username and password combinations. Consider the following:

    SYSTEM_CONNECT=system/manager

    sqlplus ${SYSTEM_CONNECT}

    In this example, sqlplus uses the contents of the SYSTEM_CONNECT variable as the username and password. ThePassword Management section goes into this in more detail.

    EXPORTING ENVIRONMENT VARIABLES

    The scope of environment variables can be expanded using the export command, but a great deal of care must be takenwhen using this command. When a variable is exported, that variable is viable to other scripts called from the process wherethe export was performed. While this can be very useful, it does pose a security problem. The ps aew command will show

    all of the exported environment variables for all other processes on the system. If a variable that contains a password isexported, this command can be used to display those values. There are possible workarounds to this, but not exportingpassword variables is the safest option.

    ScriptsIf a series of commands are placed in a file, it is called a script. To run a script, first modify the permissions on the file toinclude execute permission, and then enter its name at the command line. For instance, consider the following script called

    s1.ksh:

    datepwdwhoami

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    7/22

    UNIX Shell Scripting for Oracle Ducat

    Figure 4 - Basic script

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    8/22

    UNIX Shell Scripting for Oracle Ducat

    If this script were created using your favorite editor (which should be vi), execute permission could be granted via thefollowing command:

    chmod +x s1.ksh

    Assuming the current path contains ., simply typing s1.ksh would execute the script. If . Is not in the path, the scriptcould be executed by entering ./s1.ksh. A run of this script might look something like:

    %s1.ksh

    Sat Dec 2 13:59:28 MST 2000/common/binwducat%

    This is scripting at its most basic, and the remainder of this paper will focus on writing scripts that are more powerful.

    Throughout this paper, many scripts start with #! /bin/ksh. Even though it looks like a comment, it is not. By including thisline, UNIX will use Korn shell syntax rules regardless of the default shell.

    Parameter PassingMany scripts require parameters to be passed in to assist in processing. When calling a script from the UNIX command line,

    parameters can be included by simply including them on the same line as the command, separating then with spaces. If aparameter must contain spaces, simply enclose the parameter in double quotes.

    Once in side a KSH script, there are a few ways to obtain parameter information. The following is a list of built in variables

    that can be used:

    Variable Alternate Usage

    $# ${#} The number of parameters passed in

    $0 ${0} The basic command without any parameters$1 ${1} The first parameter passed in

    $2 ${2} The second parameter passed in

    .

    .

    .

    Consider the following example:

    #! /bin/kshecho $1

    echo $2echo $3echo $#echo $0echo Done

    The following is a sample run of this script:

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    9/22

    3

    UNIX Shell Scripting for Oracle Ducat

    % s2.ksh this is a testthisis atest

    ./s2.kshDone%

    Reading the output, the first parameter is this, the second is is a, and the third is test. Three parameters were sent, andthe command s2.ksh was run from the current directory.

    Flow Control

    One of the basic requirements of any language is that it provides the ability to control the flow of execution. Functionsprovide the ability to jump to another section of code, but what if code needs to be skipped? The Korn shell provides fourbasic constructs used in many scripts. In this paper, we use two of them. They are If and for. A brief overview of these

    constructs follows:

    IF PROCESSINGThe if command provides the ability to perform some task based on some expression. Frequently the expression involves

    comparing two numbers or two strings. The operators used to compare strings are = (equal to) and != (not equal to).Numbers are compared using the -gt (greater than), -ge (greater than or equal to), -eq (equal to), -ne (not equal), le (less than or equal to), and -lt (less than). When performing numeric comparisons, the optional test syntax should be

    used. The following code is a sample of this:

    x=5if [ test ${x} gt 0 ] ;then

    echo ${x} is greater than 0else

    echo ${x} is not greater than 0fi

    Please see a good Korn shell syntax text for more details on using the if constructs.

    FOR PROCESSINGThe for loop is very useful for processing a list of values. Consider the following example:

    for x in a b c ;doecho ${x}

    done

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    10/22

    UNIX Shell Scripting for Oracle Ducat

    This code will print out a, b, and c, each on their own line. The real power of the for loop comes in the definition of the list.The list can be a command that generates multiple lines of output. When this is the case, the loop variable takes on each line

    of output for the duration of the loop. Consider the following example:

    for x in `ls` ;domy_function ${x}

    done

    This loop would call my_function once for each file in the directory, passing the file name as a parameter.

    Identifying your processMany times a script will need to write out a temporary file. One technique used when specifying a temporary file name is toappend the current process id to the name of the file, then remove the file when the task is completed. The current process id

    can be obtained via the $$ variable. For instance, typing echo $$ at the UNIX prompt will return the current process ID(a.k.a your PID). If the PID is 12345 and the command: ls >/tmp/scrap$$.out is issued, the file scrap12345.out will becreated in the /tmp directory. If a script can be run from multiple windows simu ltaneously, this is a very good technique for

    isolating results.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    11/22

    UNIX Shell Scripting for Oracle Ducat

    Practical ExamplesThis section of the paper will use the basic concepts already discussed to build tools that are useful in an Oracle environment.

    Password ManagementOne of the classic problems in scripting involves password management. Typically, passwords end up getting hard coded,

    and this poses both security and logist ical problems. From a security standpoint, every script, which contains a hard codedpassword, must be protected so only authorized persons can view the scripts. From a logistical standpoint, when passwordsare changed, every script needs to be found and modified. One other logistical issue comes up whenever help is needed to

    debug a script. In this case, only those with t he passwords can help. Yet another comes up whenever a script is being workedon, anyone looking over your shoulder can see passwords! By using environment variables, these problems can be avoided.

    One workable solution is the creation of a script, which sets environment variables for each password. A sample of this

    script, which we will call setup_passwords.ksh, follows:

    SYSTEM_CONNECT=system/managerSYS_CONNECT=sys/change_on_install

    Figure 5 Sample setup_passwords.ksh scriptIf this script is run at the start of each script, then the variables defined can be referenced at both the UNIX and embedded

    SQL levels.

    This script should be placed in a directory common to all of those who need access, and privileges should be set so onlymembers of the group should be able to read the file. For instance, if only members of the UNIX dba group should have

    password access, then the file can be owned by the oracle account, with the group set to dba. The chmod commandshould be used to set the privileges to 770. When this is done, a ls l command on the file should look something like:

    -rwxrwx--- 1 oracle dba 79 Nov 23 13:25 setup_passwords.ksh

    Since the other group cannot see the file, the passwords are now secure from everyone except the root account, or otherusers who have your password, but that is a personal problem!

    Once we create this file, it can be used many ways. First, if it is called from your .profile2, the variables are available at the

    command line. Second, if it is run at the beginning of each script, the variables are available within the script, and others canlook at the scripts without being able to see the passwords. When calling the script, always proceed the call with a dot and aspace so variables are visible to the script. For instance, assuming the file is located in the /common/bin directory, the

    following could be added to each script:

    .b/common/bin/setup_passwords.ksh

    If this is done in the .profile, aliases could be created to log into Oracle. A sample alias follows:

    alias sqlplusS=sqlplus ${SYSTEM_CONNECT}

    From that point on, typing sqlplusS would start sqlplus as the system account for the default instance.

    *** WARNING ***

    2 The .profile file is automatically run when a new KSH session is started.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    12/22

    UNIX Shell Scripting for Oracle Ducat

    There is one very large warning here, depending on the version of UNIX being used. If a parameter password is passed to aUNIX application, and perform a ps aef in another window, all of the parameters passed in the first session may be

    shown. This includes passwords! Sqlplus is simply a UNIX application, and is subject to the same issues. Oracle has seen fitto fix this problem in some, but not all UNIX environments. For instance, if sqlplus system/manager were typed at theUNIX prompt on a Sun or HP system, the following could be seen in another window:

    % ps -aef |grep sqlplusoracle 10828 10750 0 21:35:50 ttyp1 0:00 grep sqlplusoracle 10823 10808 0 21:35:44 ttyp3 0:00 sqlplus system/manager@devel%

    Figure 6 - PS results on HP or Sun

    If the same thing is done on a Linux or Compaq/DEC environment, another ps command will show the parameters have

    been stripped off by Oracle:

    % ps -aef |grep sqlplusoracle 10979 22719 0.0 21:37:28 ttyp3 0:00.07 sqlplusoracle 32400 4008 0.5 21:37:50 ttyp4 0:00.01 grep sqlplus

    %

    Figure 7 - PS results on Compaq or Linux

    This is generally a UNIX issue, and Oracle strips off the parameters to sqlplus in some implementations. Because of this,systems should be tested before setting up such aliases.

    Another related consideration involves C programs or other scripts that take passwords as parameters. Regardless of theUNIX implementation, the passwords will be available to anyone who does a ps command, and the technique should beavoided. Scripts can be setup to get the passwords once the scripts start, and C programs can be setup to get environment

    variables as well, so this should not be a major problem. Simply be aware of the issue, and test accordingly.

    Embedded SQL

    By redirecting STDIN, SQL or PL/SQL code can be directly coded into a KORN shell script. The main advantage of thistechnique is that UNIX environment variables can be referenced within the SQL portion of the script as well as the shell area.Consider the following example:

    #! /bin/ksh

    . /common/bin/setup_passwords.ksh

    $ORACLE_HOME/bin/sqlplus -s /nolog set line 200set feedback offconnect ${SYSTEM_CONNECT};column global_name heading "Instance" format a15

    column sessions_max heading "Max" format 9999column sessions_warning heading "Warning" format 9999column sessions_current heading "Current" format 9999column sessions_highwater heading "Highwater" format 9999select

    global_name,sessions_max,sessions_warning, sessions_current-1 sessions_current,sessions_highwater

    from

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    13/22

    --------------- ----- ------- ------- ---------

    UNIX Shell Scripting for Oracle Ducat

    v\$license,global_name ;quit;!!

    Figure 8 - Embedding SQL in a KSH script

    This script will connect to oracle using the default instance and perform a series of commands that show connectioninformation. There are a few things to consider.

    o The s switch on the sqlplus command is included to remove the Oracle banner from the output.o The /nolog switch is used to avoid passing the password on the command line. We use this technique to avoid

    passing the password in case this is run on a version that does not trim off parameters as discussed in the PasswordManagement section.

    o When embedded in a KSH script, references to v$ tables must always include a \ in front of the $ character. Thisis required in a KSH script since UNIX attempts to translate the $ into environment variables.

    o Within the SQL area we issue a connect statement which references the SYSTEM_CONNECT variableWhen this script, named l1.ksh, was run on a system where the default instance is named devel, the following results wereproduced:

    %l1.kshConnected.

    Instance Max Warning Current Highwater

    DEVEL.WORLD 0 0 0 1%

    Notice the first line of the output is a line containing Connected. This line is the result of the connect statement and, as ofthis time, there is no way to get sqlplus to stop producing that output. Never fear, the Embedded Subroutines sectiondiscusses sways of dealing with this issue.

    Embedded Subroutines (aka Functions)When scripting, we do not always want to start at the top of the script, and end at the bottom. As any programmer is wellaware, the ability to create a subroutine is indispensable when creating complex code. Ksh provides this functionality in the

    form of functions embedded within the script. Consider the following script:

    #! /bin/ksh. /common/bin/setup_passwords.ksh

    __show_licenses()

    {$ORACLE_HOME/bin/sqlplus -s /nolog set line 200set feedback offconnect ${SYSTEM_CONNECT};column global_name heading "Instance" format a15column sessions_max heading "Max" format 9999column sessions_warning heading "Warning" format 9999column sessions_current heading "Current" format 9999

    column sessions_highwater heading "Highwater" format 9999select

    global_name,sessions_max,sessions_warning,

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    14/22

    --------------- ----- ------- ------- ---------

    UNIX Shell Scripting for Oracle Ducat

    sessions_current-1 sessions_current,sessions_highwater

    fromv\$license,global_name ;

    quit;

    !!}

    __show_licenses

    Figure 9 - Implementing a user-defined function in a KSH script

    In this example, we have included the definition of a function called __show_licenses. The code for the function is bracketed

    by the {} characters. The () following the function name indicates this is a function. An alternative syntax of function__show_licenses could be used if desired. When this script is run, the function is first defined, and then called by the codeon the last line. This can be verified by commenting out the last line and running the script. If this were done, the script

    would produce no output. This script produces the same output as the script in the Embedded SQL section, but with a slightchange, the problem identified in that paragraph can be eliminated.

    When we call the function on the last line, the results of the function are pushed back through STDOUT. Because of this, we

    can redirect them through any means we desire. For instance, assume we changed the last line to:

    __show_licenses >scrap.out

    In this case, nothing would be sent to the screen, but the file scrap.out would contain the output . This still does not get rid ofthe Connected. line discussed earlier, but this can be accomplished by piping the results through grep to eliminate the

    offending output. The following would accomplish this:

    __show_licenses | grep v ^Connected\.$

    This grep command would eliminate any lines containing only the string Connected. so the results would look like:

    %l3.ksh

    Instance Max Warning Current Highwater

    DEVEL.WORLD 0 0 0 1%

    One interesting thing to note is the existence of the backslash character prior to the period character. The grep command usesregular expression matching, and the period represents any one character. The backslash character indicates that the

    following special character should be interpreted literally, not as a part of a regular expression. If the backslash were

    removed, the code would eliminate lines containing things such as ConnectedX, Connectedb, etc. If this is what isdesired, then the period character can be used, but if the desire is to specifically match the period character, the backslash is

    required. This example would work with or without the backslash, but if sloppy style is used, the issue may be missed in latercode, resulting in some very hard to debug issues. In short, mean what you say, and code what you mean. There is no do as Imean, not what I say mode in UNIX, yet.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    15/22

    UNIX Shell Scripting for Oracle Ducat

    Passing ParametersUp until now, the script we have been building only works against the default instance3. By using parameters, we can

    increase the usefulness of the script. Before writing this script, there are a few issues to be considered. Parameters passed intofunctions are handled the same way as parameters passed into scripts (as discussed in the Parameter Passing section), andvariables passed to the script must be passed to the function if they are to be used by the function. Consider the following

    example:

    #! /bin/ksh__doit(){echo ${1} ${2}}echo ${1} ${2}__doit test ${1}

    The two parameters on the second to the last line will refer to the parameters passed in at the command line, and the echo

    command inside the __doit function will refer to the parameters passed in on the last line. The following run illustrates this:

    %s3.ksh aaa bbbaaa bbbtest aaa

    %

    In this case, the first parameter passed into the script contains aaa, and that value is passed as the second parameter to the

    __doit function.

    Getting back to our main script, if we modify it to expect a SID as the first parameter, then we no longer need to set ourdefault instance prior to running the script. The following shows this. Notice the parameter references on the connect line as

    well as on the call to __show_licenses.

    #! /bin/ksh. /common/bin/setup_passwords.ksh

    __show_licenses(){$ORACLE_HOME/bin/sqlplus -s /nolog column sessions_current heading "Current" format 9999column sessions_highwater heading "Highwater" format 9999select

    global_name,sessions_max,sessions_warning, sessions_current-1 sessions_current,sessions_highwater

    fromv\$license,global_name ;

    3 The default instance is the one used if no SID is passed on a connect string

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    16/22

    UNIX Shell Scripting for Oracle Ducat

    quit;!!}

    __show_licenses ${1}| grep v ^Connected\.$

    One interesting note is that if a parameter is not passed in, it ends up connecting as system/manager@. This results in a

    connection to the default instance. If this is not desired, a few lines of conditional logic could be added to the bottom in orderto verify that a parameter was sent. The following script demonstrate:

    #! /bin/ksh

    . /common/bin/setup_passwords.ksh

    __show_licenses(){$ORACLE_HOME/bin/sqlplus -s /nolog connect ${SYSTEM_CONNECT}@${1};column global_name heading "Instance" format a15

    column sessions_max heading "Max" format 9999column sessions_warning heading "Warning" format 9999column sessions_current heading "Current" format 9999column sessions_highwater heading "Highwater" format 9999select

    global_name,sessions_max,sessions_warning, sessions_current-1 sessions_current,sessions_highwater

    from

    v\$license,global_name ;quit;

    !!}

    if [ $# -ne 1 ] ;then__show_licenses ${1}| grep v ^Connected\.$

    elseecho ERROR: Invalid number of parameters specifiedecho One instance name must be specified.

    fi

    If we did not want to pass in the names of our instances, we could hard code them. Consider the following example:

    #! /bin/ksh. /common/bin/setup_passwords.ksh__show_licenses(){$ORACLE_HOME/bin/sqlplus -s /nolog www.rmoug.org RMOUG Training Days 2001

    mailto:system/manager@mailto:system/manager@
  • 7/30/2019 Unix Oracle Shell Scripting

    17/22

    --------------- ----- ------- ------- ---------

    --------------- ----- ------- ------- ---------

    --------------- ----- ------- ------- ---------

    UNIX Shell Scripting for Oracle Ducat

    column global_name heading "Instance" format a15column sessions_max heading "Max" format 9999column sessions_warning heading "Warning" format 9999column sessions_current heading "Current" format 9999column sessions_highwater heading "Highwater" format 9999

    selectglobal_name,sessions_max,sessions_warning,sessions_current-1 sessions_current,sessions_highwater

    fromv\$license,global_name ;

    quit;!!}

    __show_licenses prod|grep -v "^Connected\.$"__show_licenses devel|grep -v "^Connected\.$"__show_licenses systest|grep -v "^Connected\.$"

    This script would result in the following:

    %l6.ksh

    Instance Max Warning Current Highwater

    PROD.WORLD 0 0 0 1

    Instance Max Warning Current Highwater

    DEVEL.WORLD 0 0 0 1

    Instance Max Warning Current Highwater

    SYSTEST.WORLD 0 0 0 1%

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    18/22

    --------------- ----- ------- ------- ---------

    UNIX Shell Scripting for Oracle Ducat

    While it works, the results are not pretty. A few more modifications could correct the formatting issues:

    #! /bin/ksh. /common/bin/setup_passwords.ksh__show_licenses(){$ORACLE_HOME/bin/sqlplus -s /nolog global_name,sessions_max,sessions_warning,

    sessions_current-1 sessions_current,sessions_highwater

    fromv\$license,global_name ;

    quit;!!}

    heading=on__show_licenses prod|grep -vE "^Connected\.$|^$"heading=off__show_licenses devel|grep -vE "^Connected\.$|^$"__show_licenses systest|grep -vE "^Connected\.$|^$"

    In this case, a few changes were made. First, We added a heading environment variable and set it so only the first runwould cause the heading to be printed by sqlplus. Notice the set heading command now references the heading variablewhich is set on or off in the shell area. Next, we added the -E options to the grep so we could also exclude blank lines.

    The ^$ pattern matches any line containing only the beginning of the line immediately followed by the end of the line. Theresults of this code can be seen below:

    Instance Max Warning Current Highwater

    PROD.WORLD 0 0 0 1

    DEVEL.WORLD 0 0 0 1

    SYSTEST.WORLD 0 0 0 1

    This works well, but it is still hard coded. Every time an instance is added to the environment, the code must change. Thiscan be fixed via the creation of a global function as describes in the Global Functions section.

    Global FunctionsThere are times when it is helpful to have a small piece of code that can be called from multiple scripts. In the previousexample, we need to dynamically generate a list of instances on the machine we are running on. This code could be added to

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    19/22

    UNIX Shell Scripting for Oracle Ducat

    the script, but it is something which could be useful in multiple areas. If the code was copied to each script, maintenancewould be a problem if the logic ever changed. For instance, the first version may only work on the local machine, but if

    another machine was added, the code could be modified to pick up those instances as well. If the code is in one place, thenone change would in effect, modify all scripts.

    Our first task is to create the logic required to generate a list of instances on the local machine. For our purposes, we will

    assume the tnsnames.ora file or the Oracle Names server is configured in a manner where the instance can be reached by

    including an @ after the password on a connect string. For instance, system/manager@devel will connect to the instance witha SID of devel. Most installations that I have been involved in use this standard, but there are reasons that this standard may

    not be used. If the SID and connect information are different, appropriate changes will need to be made to the sample scripts.

    Every instance running on a machine creates what is known as a PMON process. Using the UNIX ps command, we cantake a look at these processes. Consider the following series of commands:

    %ps -aef |grep ora_pmon_oracle 863 1 0 09:11 ? 00:00:00 ora_pmon_develoracle 888 1 0 09:11 ? 00:00:00 ora_pmon_prodoracle 913 1 0 09:11 ? 00:00:00 ora_pmon_systestwducat 2584 2582 0 16:28 tty1 00:00:00 grep ora_pmon_%ps -aef |grep ora_pmon_ |grep -v grep

    oracle 863 1 0 09:11 ? 00:00:00 ora_pmon_develoracle 888 1 0 09:11 ? 00:00:00 ora_pmon_prodoracle 913 1 0 09:11 ? 00:00:00 ora_pmon_systest

    %ps -aef | \grep ora_pmon_ | \grep -vE 'sed|grep'| \sed -e 's/^.*ora_pmon_//'

    develprodsystest%

    The first command shows us all of the Oracle pmon processes as well as our grep! The second command filters out the grep.In the third command, we modify the second grep to remove the sed command also added to the third command. The sedcommand tells the system to replace everything from the beginning of the line through the ora_pmon_ with nothing. Theresult is a list of all of the currently running instances.

    The following script creates a function using the above logic to create an environment variable containing a list of allavailable instances. Line numbers are included for reference purposes.

    1 #! /bin/ksh2

    3 gen_sid_list()4 {5

    6 sid_list=""7 touch /tmp/sids_$$.out8 ps -aef | \9 grep ora_pmon | \10 grep -vE 'sed|grep'| \11 sed -e "s/^.*ora_pmon_//" \12 >/tmp/sids_$$.out

    1314 for iName in `sort /tmp/sids_$$.out` ;do15 tnsping ${iName} >/tmp/ping_$$.out

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    20/22

    UNIX Shell Scripting for Oracle Ducat

    16 eCount=`grep TNS- /tmp/ping_$$.out|wc -l`17 if [ $eCount -eq 0 ] ;then18 sid_list="${sid_list} ${iName}"19 else20 echo ERROR: Unable to connect to ${iName}

    21 fi22 rm /tmp/ping_$$.out23 done24 rm /tmp/sids_$$.out25 }

    The first thing done is the creation of a function called gen_sid_list. The placement of this function will be discussed later.The following is an analysis of the various lines in the function:

    Line

    Number Purpose

    6 Creates an empty environment variable which will ultimately contain the list ofinstances

    8 Issues the same ps command discussed above, except the results are sent to atemporary file

    14 Sets up a for loop which takes the sorted list of instance names in the temp file, andprocesses t hem one at a time, setting the variable

    15 Performs a tnsping on each instance to very if it is available. The results of the pingare sent to a temp file for further review

    16 Counts the number of TNS errors returned from the ping

    17 Determines if the instance should be added to the variable

    18 Adds the instance to the variable

    20 Displays an error if problems were found connecting to the instance

    22 Cleans up temporary file

    24 Cleans up temporary file

    If the above script is placed in another file of functions, the script can be called from multiple scripts as long as the file of

    functions is called from each script. In our example, the function was placed in a file called functions.ksh.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    21/22

    UNIX Shell Scripting for Oracle Ducat

    The following script as modified from the example in the Passing Parameters section uses this new function:

    #! /bin/ksh

    . /common/bin/setup_passwords.ksh

    . /common/bin/functions.ksh

    __show_licenses(){$ORACLE_HOME/bin/sqlplus -s /nolog connect ${SYSTEM_CONNECT}@${1};column global_name heading "Instance" format a15column sessions_max heading "Max" format 9999column sessions_warning heading "Warning" format 9999column sessions_current heading "Current" format 9999column sessions_highwater heading "Highwater" format 9999select

    global_name,sessions_max,sessions_warning,

    sessions_current-1 sessions_current,sessions_highwater

    fromv\$license,global_name ;

    quit;!!}

    gen_sid_listheading=onfor iName in $sid_list ;do

    __show_licenses ${iName}|grep -vE "^Connected\.$|^$"heading=off

    done

    Notice the addition of a call to functions.ksh at the top. This makes the gen_sid_list function available. Nothing has changed

    in the __show_licenses function. First, we call gen_sid_list to setup the sid_list environment variable. The heading variable isthen set to on for the first run. Next a for loop is setup to loop through the list of instances. Each time through the loop,the iName variable will contain the name of the next Oracle instance to process. Next, the __show_licenses function is called,

    and the instance is specified via the iName variable that is passed in as a parameter. Finally, the heading variable is set tooff for the remaining instances. This loop will be executed repeatedly for each instance.

    This code is now very generic. If a new instance is brought up on the machine, this script will automatically find it. If an

    existing instance is taken off-line, it will no longer show up.

    www.rmoug.org RMOUG Training Days 2001

  • 7/30/2019 Unix Oracle Shell Scripting

    22/22

    UNIX Shell Scripting for Oracle Ducat

    Conclusion

    The process we just went through only scratches the surface of what can be accomplished with a well-written script. Underclose inspection, a number of shortcomings become obvious in the above example. For instance, what if the Oracle instances

    are on multiple machines and we want to see them all together? What if the instance names do not match the connect strings?

    What happens if gen_sid_list generates an error? Can we get the script to stop in this case? As any programmer knows once aprogram is finished, the real work often begins as enhancements are implemented. Scripting in Korn shell is very much like

    programming in any 3GL such as C. If the task is approached from a programmers point of view, the possibilities areendless.