我们在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"
答案 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