如何在 bash 中获取 csh 脚本来设置环境
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2710790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to source a csh script in bash to set the environment
提问by Daniel
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?
我们在 Solaris 上运行 Oracle,默认情况下 shell 是 csh。因此,登录脚本也在 csh 中设置了 oracle_home 和 oracle_sid。但是我不喜欢 csh 并且想使用 bash 来完成我的工作。那么如何在bash中获取csh登录脚本呢?
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
例如,以下是 .cshrc 文件中的内容。当使用 bash 时,我想使用这些变量。一种方法是再次复制变量并使用 bash 命令,例如 export ORACLE_SID=TEST。但是这样做需要我们维护文件的两个副本。而当我们更改数据库名称,或者升级数据库时,我需要单独维护bash登录文件。使用类似的东西很好
source .cshr in bash, but it doesn't work.
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"
采纳答案by Paused until further notice.
In your ~/.bashrc
(or the first of ~/.bash_profile
, ~/.bash_login
, and ~/.profile
that exists) source this script using something like . ~/bin/sourcecsh
:
在您~/.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
This version eliminates the evil eval
:
这个版本消除了邪恶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
回答by Dave Wade-Stein
How about just defining a function called setenv, like so
像这样定义一个名为 setenv 的函数怎么样
setenv() {
echo setting to
export =
}
and then sourcing the .cshrc file.
然后获取 .cshrc 文件。
When I do this in bash, I get
当我在 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
回答by Krazy Glew
I'm in the same boat. A coworker showed me the following:
我在同一条船上。一位同事向我展示了以下内容:
Start off in bash, without the stuff in thwe environment:
从 bash 开始,没有环境中的东西:
bash> echo $$
12632
bash> echo $FOO
Here's the csh file that gets source'd:
这是获得 source'd 的 csh 文件:
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
查看 csh 的输出
FOO=some csh stuff in csh
And look at the output from the new bash shell
并查看新 bash shell 的输出
bash> echo $$
13487
bash> echo $FOO
some csh stuff
Now leave, and go back to the original bash shell
现在离开,回到原来的 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.
注意 echo $$ 以查看进程 ID,以便我们可以看到它们是不同的 shell 进程。
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/.
不幸的是,我发现我经常不仅需要设置环境变量,还需要设置别名,就像在模块包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.
我已经能够通过使用 Perl Expect 来自动化这个“csh 源脚本配方”。但是,除了上述内容之外,我还没有能够像我希望的那样进行交互。
回答by DVK
In your bash .profile
, you can do the following:
在您的 bash 中.profile
,您可以执行以下操作:
cat .cshrc | sed 's/setenv\s+(\S+)\s+(.*)$/set =; export /' > $HOME/.env_from_csh
source $HOME/.env_from_csh
回答by sblom
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.
我能想到的唯一方法是加载 csh,然后从那个新 shell 调用 bash。这样 csh 可以解析该文件,然后它产生的 bash 也将继承该环境。
回答by Keith Thompson
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 -- unlessyou generate one from the other, or generate both from a common source.
对于这么小的事情,通常需要维护两个安装脚本,一个用于 sh 和 sh 派生的 shell,另一个用于 csh 和 tcsh。正如您所提到的,这确实会造成两个脚本不同步的风险——除非您从另一个脚本生成一个,或者从一个公共源生成两个脚本。
This places the burden on the maintainer of the setup script(s) rather than on each user who needs to use them.
这将负担推给了安装脚本的维护者,而不是每个需要使用它们的用户。
回答by Mak_Thareja
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.
有一个可用的模块,您可以通过该模块在 perl 脚本中的任何位置获取相同的文件。您将在 csh 文件中获得所有可用的环境路径。
Source::Shell
Go through a little documentation for its usage.
通过一些文档了解其用法。
回答by Somesh
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.
只需#!/bin/tcsh
在 CSH 脚本的开头提供一个“ ”或类似的语句,并结合使脚本可执行,就为我解决了这个问题。在这种情况下,我可以直接从 bash 调用 CSH 脚本。
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:
例如,我必须从名为 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 ...
回答by Sid Heroor
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.
在 bash 中获取 csh 文件将不起作用。如果您更习惯使用 bash,您可以将默认登录 shell 从 csh 更改为 bash。您可以使用 chsh 或以管理员身份为您更改它。
chsh -s /usr/local/bin/bash