我试图编写一个shell脚本,当运行时,将设置一些环境变量,这些变量将在调用者的shell中保持设置。

setenv FOO foo

在csh/tcsh中,或

export FOO=foo

在sh/bash中只在脚本执行期间设置它。

我已经知道了

source myscript

将运行脚本的命令,而不是启动一个新的shell,这可能导致设置“调用者的”环境。

但问题是:

我希望这个脚本可以从bash或csh中调用。换句话说,我希望任何一个shell的用户都能够运行我的脚本,并更改他们的shell环境。因此,'source'对我来说不适用,因为运行csh的用户不能获取bash脚本的源代码,而运行bash的用户也不能获取csh脚本的源代码。

有没有合理的解决方案,不需要在脚本上编写和维护两个版本?


当前回答

您应该使用模块,参见http://modules.sourceforge.net/

编辑:模块包自2012年以来没有更新,但仍然可以正常工作。所有的新功能,铃声和口哨都发生在今天的lmod(我更喜欢它):https://www.tacc.utexas.edu/research-development/tacc-projects/lmod

其他回答

除了根据$SHELL/$TERM设置的写入条件外,没有。使用Perl有什么问题?它非常普遍(我想不出有哪个UNIX变体没有它),而且它将为您省去这些麻烦。

我很多年前就这么做了。如果我没记错的话,我在.bashrc和.cshrc中都包含了一个别名,并带了参数,以别名形式将环境设置为公共形式。

然后,您将在这两个shell中的任何一个中获取的脚本都具有带有最后一种形式的命令,该命令适用于在每个shell中使用别名。

如果我找到具体的化名,我会公布的。

简短的回答是否定的,您不能更改父进程的环境,但似乎您想要的是一个具有自定义环境变量和用户选择的shell的环境。

所以为什么不简单地

#!/usr/bin/env bash
FOO=foo $SHELL

然后,当您完成环境时,只需退出。

你可以使用别名

alias your_env='source ~/scripts/your_env.sh'

您的shell进程拥有父进程环境的副本,并且不能访问父进程的任何环境。当您的shell进程终止时,您对其环境所做的任何更改都将丢失。获取脚本文件是配置shell环境最常用的方法,您可能只想咬紧牙关,为两种shell类型各维护一个脚本文件。