我试图编写一个shell脚本,当运行时,将设置一些环境变量,这些变量将在调用者的shell中保持设置。
setenv FOO foo
在csh/tcsh中,或
export FOO=foo
在sh/bash中只在脚本执行期间设置它。
我已经知道了
source myscript
将运行脚本的命令,而不是启动一个新的shell,这可能导致设置“调用者的”环境。
但问题是:
我希望这个脚本可以从bash或csh中调用。换句话说,我希望任何一个shell的用户都能够运行我的脚本,并更改他们的shell环境。因此,'source'对我来说不适用,因为运行csh的用户不能获取bash脚本的源代码,而运行bash的用户也不能获取csh脚本的源代码。
有没有合理的解决方案,不需要在脚本上编写和维护两个版本?
这不是我所说的杰出的,但如果您需要从shell调用脚本,这也可以工作。这不是一个很好的解决方案,但对于一个单一的静态环境变量,它工作得足够好了。
1)。创建一个条件为0(成功)或1(不成功)的脚本
if [[ $foo == "True" ]]; then
exit 0
else
exit 1
2)。创建依赖于退出代码的别名。
alias='myscript.sh && export MyVariable'
调用别名,别名调用脚本,脚本计算条件,条件必须通过'&&'退出0,以便在父shell中设置环境变量。
这是垃圾,但在紧要关头可以派上用场。
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.
我没有看到任何关于如何使用协作流程来解决这个问题的说明。ssh-agent之类的常见模式是让子进程打印父进程可以求值的表达式。
bash$ eval $(shh-agent)
例如,ssh-agent可以选择Csh或与bourne兼容的输出语法。
bash$ ssh-agent
SSH2_AUTH_SOCK=/tmp/ssh-era/ssh2-10690-agent; export SSH2_AUTH_SOCK;
SSH2_AGENT_PID=10691; export SSH2_AGENT_PID;
echo Agent pid 10691;
(这会导致代理开始运行,但不允许您实际使用它,除非您现在将此输出复制粘贴到shell提示符中。)比较:
bash$ ssh-agent -c
setenv SSH2_AUTH_SOCK /tmp/ssh-era/ssh2-10751-agent;
setenv SSH2_AGENT_PID 10752;
echo Agent pid 10752;
(正如你所看到的,csh和tcsh使用setenv来设置变量。)
您自己的程序也可以做到这一点。
bash$ foo=$(makefoo)
makefoo脚本将简单地计算并打印值,并让调用者对其做任何想做的事情——将其分配给变量是一种常见的用例,但可能不希望将其硬编码到生成值的工具中。