我需要创建一个可以修改调用shell的环境变量的脚本。要允许脚本修改我使用source <script>
的环境变量,我希望bash和tcsh能够使用相同的脚本。
我认为tcsh和bash具有不同的if
语法,所以我甚至无法在脚本内部切换。处理环境变量设置的最佳方法是什么?
答案 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”程序......)