【问题标题】:Shell independent way of setting environment variableShell独立设置环境变量的方式
【发布时间】:2023-04-03 20:23:01
【问题描述】:

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

我发现 tcsh 和 bash 有不同的 if 语法,所以我什至无法在脚本内的两者之间切换。处理设置环境变量的最佳方法是什么?

【问题讨论】:

  • 检测你正在采购的脚本之外的 shell,并为 POSIX shell 和 tcsh 使用两个不同的脚本 :) 编写一个在 POSIX sh 和 tcsh 中都可以工作的脚本可能会相当痛苦(但也许实际上并非不可能,因为两者都支持 ||&&...)
  • 这就是我害怕的。谢谢你告诉我
  • 问题:你为什么使用两种不同的 shell 语言?坚持一个可能是更好的长期策略。
  • 我强烈同意 cdarke —— 做通常的事情要理智得多,并且有 yourscript.cshyourscript.bash 用于打算采购的东西,并让用户选择适当的错误。 csh 语法是 full of pitfalls,在其中写任何实质性内容都需要做出最好避免的妥协。

标签: bash shell environment-variables tcsh


【解决方案1】:

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

您尝试创建的是 bash/tcsh polyglot(我们现在假设您不想支持任何其他 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 语句中的条件后使用分号,但实际上近括号也可以,因为两者都是控制运算符,可用于结束简单命令 – if 语句中的条件实际上是一个 list,但按照 Bash 手册,它会退化为一个 简单命令。)

在 tcsh 中,它将字符串 : 与字符串 : 进行比较——因为它们相等,并且我们正在测试是否不相等,所以它执行第二个分支。

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


关于注意事项,您在 POSIX shell 部分中实际可以执行的操作有些限制:例如,您不能使用 POSIX 语法 (foo() {...}) 定义任何函数,因为 tcsh 会抱怨括号,尽管 Bash 语法 (function foo {...}) 有效。我认为 tcsh 部分也有类似的限制。

这种多语言也不能在fish中工作,虽然它在zsh中工作。 (这就是为什么条件是: != : 而不是: == '' 之类的东西——在zsh 中,== 扩展为命令= 的路径,它不存在。)它似乎也适用于ksh(尽管在这一点上,它变得不再是一个多语言的,更多的是一个“是这个 shell csh”程序......)

【讨论】:

  • aside: function foo { ... } 可以追溯到 POSIX 之前的 ksh;它是混合的function foo() { ... },这是一种bashism,既不兼容POSIX也不兼容ksh。
  • @CharlesDuffy 哦,哇,这真的很酷——我不知道。听起来人们经常称之为 bashism 的其他一些功能,例如 [[,实际上也来自 ksh!
【解决方案2】:

我讨厌写一个答案,只是扩展@Ash 对原始问题的评论。但我觉得重要的是要注意,您不仅需要考虑 POSIX 1003 shell(如 bash)和经典 shell(如 csh/tcsh)。您还需要考虑现代替代方案,例如 fish,它与这些 shell 中的任何一个都不兼容。

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

【讨论】:

    猜你喜欢
    • 2021-03-28
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 2012-09-14
    • 2016-01-26
    • 2012-10-01
    相关资源
    最近更新 更多