我试图编写一个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中设置环境变量。
这是垃圾,但在紧要关头可以派上用场。
我没有看到任何关于如何使用协作流程来解决这个问题的说明。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脚本将简单地计算并打印值,并让调用者对其做任何想做的事情——将其分配给变量是一种常见的用例,但可能不希望将其硬编码到生成值的工具中。
您将无法修改调用者的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新闻服务器中也有类似的功能。