Shell独立设置环境变量的方式

时间:2018-05-24 23:10:52

标签: bash shell environment-variables tcsh

我需要创建一个可以修改调用shell的环境变量的脚本。要允许脚本修改我使用source <script>的环境变量,我希望bash和tcsh能够使用相同的脚本。

我认为tcsh和bash具有不同的if语法,所以我甚至无法在脚本内部切换。处理环境变量设置的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

我讨厌写一个答案,只是扩展@Josh对原始问题的评论。但我觉得重要的是要注意你不仅需要考虑像bash这样的POSIX 1003 shell和像csh / tcsh这样的经典shell。您还需要考虑像fish这样的现代替代方案,它们与这两种方法都不兼容。

正如@Josh所说,解决方案是为每个调用shell使用“bridge”代码,这些代码将信息映射到适合调用shell的语法中。

答案 1 :(得分:1)

好的,you got me。我做了一些实验,你实际上可以用一个脚本来做这个。 (更新:我比原版更复杂,这是一个更好的解决方案,也适用于zsh。)

您要创建的是bash / tcsh 多语言(我们现在假设您不想支持任何其他shell)。我会把实际的多语言放在这里,之后会有一些解释和注意事项:

if ( : != : ) then
    echo "In a POSIX shell or zsh or ksh"
else
    echo "In tcsh"
    alias fi :
endif
fi

第一行真的是这个多语言中的有趣位。

在POSIX sh中,它创建一个子shell来运行带有两个参数:==的命令::总是返回true,因此执行if语句的第一个分支。 (通常在if语句中的条件之后使用分号,但事实上close-paren也可以,因为它们都是控制运算符,可以用来结束简单命令 - if语句中的条件实际上是列表,但是它会退化为简单命令,由Bash手册完成。)

在tcsh中,它将字符串:与字符串:进行比较 - 因为它们相等,我们正在测试不等式,它会执行第二个分支。

第二个(tcsh)分支的最后一行只是确保tcsh不会抱怨最终的fi不是命令。在第一个分支中不需要类似的别名,因为endif仍然在if语句的第二个分支中,就POSIX shell而言。

关于警告,你在POSIX shell部分实际上做的有些限制:例如,你不能使用POSIX语法(foo() {...})定义任何函数,因为tcsh将抱怨括号,尽管Bash语法(function foo {...})有效。我假设tcsh部分有类似的限制。

这种多语言在鱼类中也不起作用,尽管它在zsh中起作用。 (这就是条件为: != :而不是: == ''的原因 - 在zsh中,==扩展到命令=的路径,该命令不存在。)也似乎在ksh中工作(尽管此时它变成了一个多语言,更多的是“这个shell csh”程序......)