如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:14:03  来源:igfitidea点击:

how to source a csh script in bash to set the environment

bashcsh

提问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 ~/.profilethat 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