tags:

views:

810

answers:

4

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 maintian the bash login file seperately. 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"
A: 

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.

sblom
A: 

Sourcing a csh file in bash will not work. You can change the default login shell from csh to bash if you are more confortable in bash. You could use chsh or as an admin to change it for you.

chsh -s /usr/local/bin/bash 
Sid H
+3  A: 

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
Dennis Williamson
@Dennis - nice... I like this one since it's pure bash (mine uses `sed`)... I must admit that I still prefer my version (fairly similar) mostly since it keeps the list of set commands as a file for later troubleshooting or environment restoration just in case :)
DVK
I'll vote for the first version -- sourcing stdin is at least as trouble-prone as `eval`.
Gordon Davisson
+1  A: 

In your bash .profile, you can do the following:

cat .cshrc | sed 's/setenv\s+(\S+)\s+(.*)$/set $1=$2; export $1/' > $HOME/.env_from_csh
source $HOME/.env_from_csh
DVK
It's also cool, I prefer not create some junk file. Not sure whether we can just use pipe to avoid the temporary file.
Daniel
Useless use of `cat`. Bash doesn't use `set` that way. `export` can take the variable name and assignment all at once. You must be using a different version of `sed` because that looks like Perl syntax. You need to use `-r` or escape the parentheses and plus signs. You can eliminate the temporary file like this: `source /dev/stdin < <(sed 's/setenv\s\+\(\S\+\)\s\+\(.*\)$/export \1=\2/' .cshrc)`
Dennis Williamson
@Dennis and Daniel - I usually **want** that "junk" temporary file :)
DVK
`source /dev/stdin < <(sed 's/setenv\s\+\(\S\+\)\s\+\(.*\)$/export \1=\2/' .cshrc | tee $HOME/.env_from_csh)`
Dennis Williamson
@Dennis - neat!
DVK