我正在与数据分析项目的某个人合作,我们经常通过将它们放入小型shell脚本中来记录我们执行的步骤。问题是我使用bash而另一个人使用csh。另一个人习惯使用source
来运行这些脚本而不是直接执行它们(这个习惯可能追溯到产生额外shell的时候是浪费资源的浪费,所以它可能根本不能改变) ,我想让我的脚本(当然是bash脚本)只是停留一条消息,提醒用户使用bash而不是csh运行它们,当这个人从csh中获取它们时。同时,我希望它们继续作为bash脚本运行。
因此,我可以在脚本的开头添加一些代码,这些代码是bash中的无操作但会发出错误并取消执行文件的其余部分(但不会杀死shell本身)来自cshell?
答案 0 :(得分:6)
由于csh古老的变量替代味道,这比我想象的要难。但是,$?BASH_VERSION
在bash中扩展为0(未设置),并在bash中扩展为0BASH_VERSION
(或者最后一个命令'RV')。所以,
test "$?BASH_VERSION" = 0 && exit 1
应该做的伎俩。
答案 1 :(得分:1)
这并不容易,因为您无法以相同的方式分配变量或以相同的方式运行if语句。
您可以使用csh的微弱字符串解析技巧。以下在所有shell中执行干净,包括KSH,BASH,ZSH,CSH和SH在我测试它的所有平台上(Linux,AIX,HP-UX,Solaris):
test '\\' = "\\" && echo "CSH detected"
这里使用的想法是CSH上的双引号字符串中的反斜杠并不特殊,而所有其他shell确实将它们视为不同。
但是,如果您不想在检测到“错误”的shell时只想退出脚本,那么这只是您想要做的一半答案?好吧,您可能希望在脚本和sh
部分中使用Bournish csh
部分。
如果您可以将csh
代码限制为不使用单引号的代码,则以下内容适用于所有地方:
test '\\' = "\\" && goto csh
# Just skip the block containing the csh code. Again we use csh's meagre string parsing capabilities against it.
false || csh_code_block='
csh:
... csh code goes here ...
exit 0
'
... sh code goes here ...
如果您不担心HP-UX的csh
(在解析方面似乎比其他人好一点),您可以使用“HERE”文档替换多行单引号命令(<<CSH_BLOCK ... CSH_BLOCK
)。您也不能只是颠倒顺序,因为'goto'语句不喜欢它跳过的所有语法。