So my organization is upgrading our Oracle database from 11g to 19c.
Previously, in my makefile, I had been setting ORACLE_HOME like this:
ORACLE_HOME=/opt/app/oracle/product/11.2.0.4/db_1
However, Oracle 19c has a fun feature that whenever they run a patch on it, the db_1 changes incrementally, becoming db_2, then db_3, with each patch, etc.
So obviously I can't hardcode the ORACLE_HOME path anymore.
In a bunch of my scripts, I'm pulling the current value from the ortab file, like this:
setenv ORACLE_SID DATABASE1
setenv ORACLE_HOME `cat /var/opt/oracle/oratab | sed 's/#.*//g' | grep -w $ORACLE_SID | awk -F: '{print $2;}'`
And this is working just fine, pulling the correct ORACLE_HOME path from the ortab file.
However, when I tried to do this in a makefile, like so:
ORACLE_SID=DATABASE1
ORACLE_HOME=`cat /var/opt/oracle/oratab | sed 's/#.*//g' | grep -w $ORACLE_SID | awk -F: '{print $2;}'`
I get this error when I try to run make:
$ make
`cat /var/opt/oracle/oratab | sed 's//bin/proc sys_include=/usr/include lines=yes iname=file1.pc oname=file1.c include=/path/to/include
First RE may not be null
*** Error code 2
make: Fatal error: Command failed for target `file1.o'
So obviously the command isn't working the way I'm expecting, but I am unsure how to fix it.
How do I fix the command to work inside makefile? I'm running Solaris 11.
This is not GNU make, this is just the default make that comes with Solaris 11.
Adding more information:
My ortab file looks like this:
$cat /var/opt/oracle/oratab
DATABASE_TEST:/opt/app/oracle/product/11.2.0.4/db_7:Y
DATABASE1:/opt/app/oracle/product/19.0.0.0/db_3:N
DATABASE2:/opt/app/oracle/product/11.2.0.4/db_13:Y
DATABASE3:/opt/app/oracle/product/11.2.0.4/db_1:Y
DATABASE_PROD:/opt/app/oracle/product/11.2.0.4/db_2:Y
So, what I need to do, is using the ORACLE_SID of DATABASE1, pull out the /opt/app/oracle/product/19.0.0.0/db_3
part, to use as my ORACLE_HOME directory in the makefile.
Update: Based on an answer below from MadScientist , this is now my makefile:
ORACLE_SID=DATABASE1
#ORACLE_HOME = /opt/app/oracle/product/19.0.0/db_3
ORACLE_HOME = `cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w ${ORACLE_SID} | awk -F: '{print $$2;}'`
PROC=${ORACLE_HOME}/bin/proc
E_INCLUDE=/path/to/include
print-% : ; @echo $* = $($*)
file1.o: file1.pc
${PROC} sys_include=/usr/include lines=yes iname=$*.pc oname=$*.c include=${E_INCLUDE}
When I hardcode ORACLE_HOME, everything works correctly.
When I try to use the dynamically created ORACLE_HOME, I get this error:
$ make
`cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w DATABASE1 | awk -F: '{print $2;}'`/bin/proc sys_include=/usr/include lines=yes iname=file1.pc oname=file1.c include=/path/to/include
make: Fatal error: Command failed for target `file1.o'
So it looks like it's setting ORACLE_HOME as the command itself, rather than as the result of the command.
Weirdly, when I run make print-ORACLE_HOME, I get the expected result /opt/app/oracle/product/19.0.0/db_3
I finally got it to work.
Using @Milag 's answer regarding the :sh command substitution, I was able to find the documentation regarding that for Solaris (not GNU) make: link to documentation
THIS was the answer:
ORACLE_HOME :sh =cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w DATABASE1 | awk -F: '{print $2;}'
The key? NOT putting a double dollar sign, as the documentation said:
"In contrast to commands in rules, the command is not subject for macro substitution; therefore, a dollar sign ($) need not be replaced with a double dollar sign ($$)."
Because of this I also had to hardcode DATABASE1
instead of using the ${ORACLE_SID} variable, but since that value will never change, I can live with that.