如何在bash中使用csh脚本来设置环境

时间:2010-04-26 02:23:51

标签: bash csh

我们在Solaris上运行Oracle,默认情况下shell是csh。所以登录脚本也在csh中设置oracle_home,oracle_sid。但是我不喜欢csh而且想用bash来完成我的工作。那么如何在bash中使用csh登录脚本?

例如,以下是.cshrc文件中的内容。当使用bash时,我想使用这些变量。一种方法是再次复制变量并使用bash命令,例如export ORACLE_SID = TEST。但这样做需要我们维护两份文件。当我们更改数据库名称或升级数据库时,我需要单独维护bash登录文件。很高兴使用像

这样的东西

在bash中使用.cshr,但它不起作用。

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"

9 个答案:

答案 0 :(得分:17)

~/.bashrc(或~/.bash_profile中的第一个,~/.bash_login~/.profile中,使用. ~/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

此版本消除了邪恶的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
)

修改

没有采购stdin:

while read cmd var val
do
    if [[ $cmd == "setenv" ]]
    then
        declare -x "$var=$val"
    fi
done < cshrc

答案 1 :(得分:4)

我在同一条船上。一位同事向我展示了以下内容:

从bash开始,没有东西在环境中:

bash> echo $$
12632
bash> echo $FOO

以下是获取源代码的csh文件:

bash> cat setup-env.csh
setenv FOO "some csh stuff"
echo FOO=$FOO in csh

这是命令:

bash> csh -c 'source setup-env.csh;exec bash'

查看csh的输出

FOO=some csh stuff in csh

查看新bash shell的输出

  bash> echo $$
  13487
  bash> echo $FOO
  some csh stuff

现在离开,然后回到原来的bash shell

bash> exit
exit
bash> echo $$
12632
bash> 

请注意echo $$以查看进程ID,以便我们可以看到它们是不同的shell进程。

我的同事使用了这个,他把它放入别名,如:

# 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

不幸的是,我发现我经常不仅需要环境变量设置,还需要别名设置,就像在模块包http://modules.sourceforge.net/中一样。

我已经能够使用Perl Expect自动化这个“csh源脚本配方”。但除了上述情况之外,我无法像我想的那样互动。

答案 2 :(得分:3)

如何定义一个名为setenv的函数,如此

setenv() {
  echo setting $1 to $2
  export $1=$2
}

然后获取.cshrc文件。

当我在bash中这样做时,我得到了

[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

答案 3 :(得分:2)

在bash .profile中,您可以执行以下操作:

cat .cshrc | sed 's/setenv\s+(\S+)\s+(.*)$/set $1=$2; export $1/' > $HOME/.env_from_csh
source $HOME/.env_from_csh

答案 4 :(得分:1)

我能想到的唯一方法就是加载csh然后从那个新shell调用bash。这样csh就可以解析该文件,然后它产生的bash也将继承该环境。

答案 5 :(得分:0)

对于小的东西,维护两个设置脚本是常见的,一个用于sh和sh派生的shell,另一个用于csh和tcsh。正如您所提到的那样,这确实会造成两个脚本不同步的风险 - ,除非您从另一个脚本生成一个脚本,或者从公共源生成两个脚本。

这会给安装脚本的维护者带来负担,而不是每个需要使用它们的用户。

答案 6 :(得分:0)

有一个模块可用于在perl脚本中根据需要获取相同的文件。并且您将获得csh文件中可用的所有环境路径。

Source::Shell

查看一些文档,了解其用法。

答案 7 :(得分:-1)

只需在CSH脚本开头提供“#!/bin/tcsh”或类似语句,同时使脚本可执行即可解决问题。在这种情况下,我可以直接从bash调用CSH脚本。

例如,我必须从名为setup.sh的bash脚本运行tools.csh。我在bash脚本中做了类似的事情:

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 ...

答案 8 :(得分:-4)

在bash中获取csh文件不起作用。如果你在bash中更加舒适,可以将默认登录shell从csh更改为bash。您可以使用chsh或管理员为您更改它。

chsh -s /usr/local/bin/bash