Find listeners in listener.ora from ORACLE_HOME

I wrote my command line processing ksh script as part of a generalized adrci error checker.  One of the things I would like my error checker to do is check for listeners. I have a variety of ways I can do this:  use ps -elf | grep lsnr to find running listeners.  Use adrci to look for listeners under the ORACLE_BASE of my ORACLE_HOME directories (from /etc/oratab or the Oracle inventory).

I want to allow a specific listener to be chosen.  This is a bit of a problem for me.  I have three listeners and they run from three different Oracle homes.  I can probably deal with this.  I should have a list of available Oracle homes in /etc/oratab.  If I input a listener name, I can check all the listed homes until I find the right one for the listener.  Or I can check all the homes to find all the listeners.

But I have to grep $ORACLE_HOME/network/admin/listener.ora to find the listeners.  And I have to be careful. For example, I want

  • LISTENER=
  • LISTENER[TAB] [TAB]  =
  • LISTENER_ABC=
  • [TAB]LISTENER_ABC = # My LISTENER_ABC comment

etc.

But I do not want

SID_LIST_LISTENER_ABC =

# LISTENER=

or their kin.

I tried a lot of things that did not work and eventually went with the following.

$ grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=” $ORACLE_HOME/network/admin/listener.ora
LISTENER_ABC =

The regular expression means find all lines that start with listener followed by an optional underscore, then optional alphabetic characters, then optional blanks (tab or spaces) and an equal sign.

Here are some additional tests.

echo “LISTENER = ” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER =

$ echo “#LISTENER_ABC=” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”

$ echo “LISTENER_ABC=” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC=

$ echo “LISTENER_ABC =” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC =

$ echo ” LISTENER_ABC =” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC =

$ echo ” LISTENER_ABC =” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC =

$ echo ” LISTENER_ABC = # My LISTENER_ABC comment” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC = # My LISTENER_ABC comment

$ echo “SID_LIST_LISTENER_ABC = ” | grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=”

I should now be able to extract a list of listeners from my listener.ora files.

I made a fake file (because my listener.ora files all have one listener).

LISTENER_ABC =
LISTENER_XYZ =
LISTENER_N =

Notice that the file contains some tabs.

$ grep $’\t’ listener.ora
LISTENER_XYZ =
LISTENER_N =

The command below is actually all I need to create an array (in ksh) of listeners from a listener.ora file.

$ set -A LISTENERS `grep -i “^[[:blank:]]*listener_*[[:alpha:]]*[[:blank:]]*=” listener.ora | cut -d’=’ -f1`
$ echo ${LISTENERS[*]}
LISTENER_ABC LISTENER_XYZ LISTENER_N

Notice that as a bonus I lost the blank characters.  (Index 2 in the array is the third element LISTENER_N).

$ echo ${LISTENERS[2]} | grep $’\t’

I tried to use word boundaries in grep (/b is the start of a word), but could not get the “not proceeded by a #” into the word.  I had trouble with the trailing equal sign with word boundaries too.  My word got too long and had non-word characters.  Since I did not want to specify a word boundary at the end of the word, it was challenging.

Arguably, I could look for just 0 or 1 underscores, but I am not certain if Oracle lets me start a listener name with an underscore.

$ echo “LISTENER_ABC=” | grep -i “^[[:blank:]]*listener_\{0,1\}[[:alpha:]]*[[:blank:]]*=”
LISTENER_ABC=
$ echo “LISTENER__ABC=” | grep -i “^[[:blank:]]*listener_\{0,1\}[[:alpha:]]*[[:blank:]]*=”

I really need to use use the alphanumeric character class and possibly allow additional underscores in the name.

$ echo “LISTENER_ABC_123=” | grep -i “^[[:blank:]]*listener_\{0,1\}[[:alnum:]_]*[[:blank:]]*=”
LISTENER_ABC_123=

I added LISTENER_123_B to my fake listener.ora file to show that the revised search string matches numeric listeners with additional underscores.

$ set -A LISTENERS `grep -i “^[[:blank:]]*listener_\{0,1\}[[:alnum:]_]*[[:blank:]]*=” listener.ora | cut -d’=’ -f1`
$ echo ${LISTENERS[*]}
LISTENER_ABC LISTENER_XYZ LISTENER_N LISTENER_123_B

Bye.