We have Oracle running on Solaris, and the shell is by default csh. So the login script sets the oracle_home, oracle_sid in csh also. But I don't like csh and want to use bash to do my work. So how to source the csh login script in bash?
e.g, the following is what in the .cshrc file. And when use bash, I'd like use these variables. One way is to copy the variables again and use bash command, such as export ORACLE_SID=TEST. But doing so will require us to maintain two copies of the files. And when we change the database name, or upgrade the database, I need to maintain the bash login file separately. It's nice to just use something like
source .cshr in bash, but it doesn't work.
setenv ORACLE_SID TEST setenv ORACLE_HOME /oracle/TEST/home/products/10204 setenv EPC_DISABLED TRUE setenv MANPATH /usr/local/man:/usr/share/man setenv EDITOR vi setenv LD_LIBRARY_PATH $ORACLE_HOME/lib:/usr/sfw/lib/64 setenv NLS_LANG AMERICAN_AMERICA.UTF8 setenv NLS_DATE_FORMAT "DD-MON-RR"
In order to set a permanent environment variable in Bash, you have to use the export command and add it either to your “. bashrc” file (if this variable is only for you) or to the /etc/environment file if you want all users to have this environment variable.
To set an environment variable everytime, use the export command in the . bashrc file (or the appropriate initialization file for your shell). To set an environment variable from a script, use the export command in the script, and then source the script. If you execute the script it will not work.
In your ~/.bashrc
(or the first of ~/.bash_profile
, ~/.bash_login
, and ~/.profile
that exists) source this script using something like . ~/bin/sourcecsh
:
#!/bin/bash
# This should be sourced rather than executed
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
eval "export $var=$val"
fi
done < ~/.cshrc
This version eliminates the evil eval
:
#!/bin/bash
# This should be sourced rather than executed
# yes, it will be sourcing within sourcing - what so(u)rcery!
source /dev/stdin < \
<(
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
echo "export $var=$val"
fi
done < cshrc
)
Edit:
Without sourcing stdin:
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
declare -x "$var=$val"
fi
done < cshrc
How about just defining a function called setenv, like so
setenv() {
echo setting $1 to $2
export $1=$2
}
and then sourcing the .cshrc file.
When I do this in bash, I get
[dws@oxygen ual-read-only]$ source cshrc
setting ORACLE_SID to TEST
setting ORACLE_HOME to /oracle/TEST/home/products/10204
setting EPC_DISABLED to TRUE
setting MANPATH to /usr/local/man:/usr/share/man
setting EDITOR to vi
setting LD_LIBRARY_PATH to /oracle/TEST/home/products/10204/lib:/usr/sfw/lib/64
setting NLS_LANG to AMERICAN_AMERICA.UTF8
setting NLS_DATE_FORMAT to DD-MON-RR
[dws@oxygen ual-read-only]$ env | grep ORACLE
ORACLE_SID=TEST
ORACLE_HOME=/oracle/TEST/home/products/10204
I'm in the same boat. A coworker showed me the following:
Start off in bash, without the stuff in thwe environment:
bash> echo $$
12632
bash> echo $FOO
Here's the csh file that gets source'd:
bash> cat setup-env.csh
setenv FOO "some csh stuff"
echo FOO=$FOO in csh
Here's the command:
bash> csh -c 'source setup-env.csh;exec bash'
Look at the output from csh
FOO=some csh stuff in csh
And look at the output from the new bash shell
bash> echo $$
13487
bash> echo $FOO
some csh stuff
Now leave, and go back to the original bash shell
bash> exit
exit
bash> echo $$
12632
bash>
Note the echo $$ to see the process IDs, so that we can see they are different shell processes.
My coworker uses this enough that he puts it into an alias, like:
# make csh environment scripts useable (sourceable) from bash function
# from Phil McCoy, Wed Nov 9 2011
source_csh () {
exec csh -c " source $*; setenv ALREADY_SOURCED \"$ALREADY_SOURCED:$*:\"; exec bash"
}
# sounds like a great idea to do source_csh .cshrc or .login
# but naively done is infinitely recursive,
# since the exec'ed bash will run .bashrc
Unfortunately, I have found that I often needed not just environment variable setup, but also aliases setup, as in the modules package http://modules.sourceforge.net/.
I have been able to automate this "csh source script recipes" by using Perl Expect. But I have not been able to be as interactive as I would like, except for the above.
Only way I can think to do it would be to load csh and then call bash from that new shell. That way csh could parse that file, and then the bash that it spawns would inherit that environment as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With