我试图编写一个shell脚本,当运行时,将设置一些环境变量,这些变量将在调用者的shell中保持设置。
setenv FOO foo
在csh/tcsh中,或
export FOO=foo
在sh/bash中只在脚本执行期间设置它。
我已经知道了
source myscript
将运行脚本的命令,而不是启动一个新的shell,这可能导致设置“调用者的”环境。
但问题是:
我希望这个脚本可以从bash或csh中调用。换句话说,我希望任何一个shell的用户都能够运行我的脚本,并更改他们的shell环境。因此,'source'对我来说不适用,因为运行csh的用户不能获取bash脚本的源代码,而运行bash的用户也不能获取csh脚本的源代码。
有没有合理的解决方案,不需要在脚本上编写和维护两个版本?
使用“点空格脚本”调用语法。例如,下面是如何使用脚本的完整路径:
. /path/to/set_env_vars.sh
如果你和脚本在同一个目录中,下面是如何做到这一点:
. set_env_vars.sh
它们在当前shell下执行脚本,而不是加载另一个脚本(如果您执行./set_env_vars.sh,就会发生这种情况)。因为它在同一个shell中运行,所以当它退出时,您设置的环境变量将可用。
这与调用源set_env_vars.sh是一样的事情,但它的输入更短,并且可能在源不能工作的某些地方工作。
Another option is to use "Environment Modules" (http://modules.sourceforge.net/). This unfortunately introduces a third language into the mix. You define the environment with the language of Tcl, but there are a few handy commands for typical modifications (prepend vs. append vs set). You will also need to have environment modules installed. You can then use module load *XXX* to name the environment you want. The module command is basically a fancy alias for the eval mechanism described above by Thomas Kammeyer. The main advantage here is that you can maintain the environment in one language and rely on "Environment Modules" to translate it to sh, ksh, bash, csh, tcsh, zsh, python (?!?!!), etc.
您将无法修改调用者的shell,因为它位于不同的进程上下文中。当子进程继承shell的变量时,它们会
继承副本本身。
您可以做的一件事是编写一个脚本,为tcsh发出正确的命令
或者基于调用方式的sh。如果你的脚本是“setit”,那么执行:
ln -s setit setit-sh
and
ln -s setit setit-csh
现在,您可以直接或在别名中从sh执行此操作
eval `setit-sh`
或者这个来自CSH
eval `setit-csh`
Setit使用$0来确定其输出样式。
这让人想起人们如何得到TERM环境变量集。
这里的优点是,setit只写在你喜欢的任何shell中,比如:
#!/bin/bash
arg0=$0
arg0=${arg0##*/}
for nv in \
NAME1=VALUE1 \
NAME2=VALUE2
do
if [ x$arg0 = xsetit-sh ]; then
echo 'export '$nv' ;'
elif [ x$arg0 = xsetit-csh ]; then
echo 'setenv '${nv%%=*}' '${nv##*=}' ;'
fi
done
使用上面给出的符号链接和反引号表达式的eval,可以得到预期的结果。
简化csh、tcsh或类似shell的调用:
alias dosetit 'eval `setit-csh`'
或者用于sh、bash等:
alias dosetit='eval `setit-sh`'
这样做的一个好处是,您只需要在一个地方维护列表。
理论上,你甚至可以把列表放在一个文件中,把cat nvpairfilename放在“In”和“do”之间。
这基本上就是登录shell终端设置的方式:脚本将输出要在登录shell中执行的语句。别名通常用于简化调用,如“tset vt100”。正如在另一个回答中提到的,INN UseNet新闻服务器中也有类似的功能。
这不是我所说的杰出的,但如果您需要从shell调用脚本,这也可以工作。这不是一个很好的解决方案,但对于一个单一的静态环境变量,它工作得足够好了。
1)。创建一个条件为0(成功)或1(不成功)的脚本
if [[ $foo == "True" ]]; then
exit 0
else
exit 1
2)。创建依赖于退出代码的别名。
alias='myscript.sh && export MyVariable'
调用别名,别名调用脚本,脚本计算条件,条件必须通过'&&'退出0,以便在父shell中设置环境变量。
这是垃圾,但在紧要关头可以派上用场。