代码是bash中的无操作但在csh中停止并显示错误消息?

时间:2011-11-21 20:36:46

标签: bash csh

我正在与数据分析项目的某个人合作,我们经常通过将它们放入小型shell脚本中来记录我们执行的步骤。问题是我使用bash而另一个人使用csh。另一个人习惯使用source来运行这些脚本而不是直接执行它们(这个习惯可能追溯到产生额外shell的时候是浪费资源的浪费,所以它可能根本不能改变) ,我想让我的脚本(当然是bash脚本)只是停留一条消息,提醒用户使用bash而不是csh运行它们,当这个人从csh中获取它们时。同时,我希望它们继续作为bash脚本运行。

因此,我可以在脚本的开头添加一些代码,这些代码是bash中的无操作但会发出错误并取消执行文件的其余部分(但不会杀死shell本身)来自cshell?

2 个答案:

答案 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'语句不喜欢它跳过的所有语法。