21

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"
4

9 に答える 9

19

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
于 2010-04-26T02:41:31.240 に答える
6

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
于 2011-11-17T18:00:45.290 に答える
4

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.

于 2012-01-24T05:23:16.247 に答える
2

私が考えることができる唯一の方法は、cshをロードしてから、その新しいシェルからbashを呼び出すことです。そうすれば、cshはそのファイルを解析でき、それが生成するbashもその環境を継承します。

于 2010-04-26T02:26:50.817 に答える
2

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
于 2010-04-26T02:47:43.673 に答える
0

For something that small, it's common to maintain two setup scripts, one for sh and sh-derived, shells, and one for csh and tcsh. As you mention, that does create the risk of the two scripts getting out of sync -- unless you generate one from the other, or generate both from a common source.

This places the burden on the maintainer of the setup script(s) rather than on each user who needs to use them.

于 2012-01-24T05:35:45.507 に答える
0

There is a module available by which you can source same file where ever you want in perl script. And you will get all environment paths available in your csh file.

Source::Shell

Go through a little documentation for its usage.

于 2013-07-10T05:49:35.627 に答える
-1

Just having a "#!/bin/tcsh" or similar statement available at the start of the CSH script in conjunction with making the script executable solved the problem for me. I could directly call the CSH script from bash in this case.

As an example, I had to run tools.csh from a bash script called setup.sh. I did something like this in the bash script:

if [ -z \`head -1 tools.csh | grep '^#!'\` ];
then
   TCSH=\`which tcsh\`;
   echo "'#!'$TCSH" > tools.csh.temp;
   cat tools.csh >> tools.csh.temp;
   mv tools.csh.temp tools.csh;
fi;
chmod 755 tools.csh;
./tools.csh
# now I have all the setenv commands effective ...
于 2010-12-13T08:35:25.747 に答える
-4

bashでcshファイルを調達することはできません。bashに慣れている場合は、デフォルトのログインシェルをcshからbashに変更できます。chshを使用するか、管理者として使用して変更できます。

chsh -s /usr/local/bin/bash 
于 2010-04-26T02:30:09.077 に答える