shell脚本可以设置调用shell的环境变量吗?

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

setenv FOO foo

在csh / tcsh中,或者

export FOO=foo

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

我已经知道了

source myscript

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

但是这是一个难题:

我希望这个脚本可以从bash或csh中调用。 换句话说,我希望任何一个shell的用户都能够运行我的脚本并改变shell的环境。 所以'源'不适合我,因为运行csh的用户无法获取bash脚本,而运行bash的用户无法获取csh脚本。

是否有任何合理的解决方案不涉及必须在脚本上编写和维护两个版本?


您的shell进程拥有父级环境的副本,无论如何都无法访问父进程的环境。 当您的shell进程终止您对其环境所做的任何更改时,都会丢失。 采购脚本文件是配置shell环境最常用的方法,您可能只想咬一口并为两种shell的每一种维护一个。


使用“点空间脚本”调用语法。 例如,以下是如何使用脚本的完整路径进行操作的方法:

. /path/to/set_env_vars.sh

以下是如何与脚本位于同一目录中的方法:

. set_env_vars.sh

这些脚本在当前shell下执行脚本,而不是加载另一个脚本(如果执行./set_env_vars.sh会发生这种情况)。 因为它运行在同一个shell中,所设置的环境变量将在退出时可用。

这与调用source set_env_vars.sh是一样的,但是它的输入时间较短,并且可能在某些source不可用的地方工作。


你不能修改调用者的shell,因为它在不同的进程上下文中。 当子进程继承你的shell的变量时,它们自己继承副本。

你可以做的一件事是编写一个脚本,该脚本根据tcsh或sh的调用方式发出正确的命令。 如果你的脚本是“setit”,那么做:

ln -s setit setit-sh

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

用上面给出的符号链接和反引用表达式的评估,这具有期望的结果。

为了简化对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新闻服务器也有类似的功能。

链接地址: http://www.djcxy.com/p/4347.html

上一篇: Can a shell script set environment variables of the calling shell?

下一篇: How to iterate over arguments in a Bash script