在bash中是no-op但在csh中停止并显示错误消息的代码?

在bash中是no-op但在csh中停止并显示错误消息的代码?,bash,csh,Bash,Csh,我和某人一起做一个数据分析项目,我们经常将执行的步骤记录到小的shell脚本中。问题是我使用bash,而另一个人使用csh。另一个人有使用source来运行这些脚本的习惯,而不是直接执行它们(这个习惯可能要追溯到产生额外的shell是一种额外的资源浪费的时代,所以它可能太根深蒂固而无法更改),我想拥有我的脚本(当然是bash脚本)当用户从csh中获取它们时,只需发送一条消息提醒用户使用bash而不是csh来运行它们。同时,我希望它们继续充当bash脚本 那么,是否有一些代码可以放在脚本的开头,这

我和某人一起做一个数据分析项目,我们经常将执行的步骤记录到小的shell脚本中。问题是我使用bash,而另一个人使用csh。另一个人有使用
source
来运行这些脚本的习惯,而不是直接执行它们(这个习惯可能要追溯到产生额外的shell是一种额外的资源浪费的时代,所以它可能太根深蒂固而无法更改),我想拥有我的脚本(当然是bash脚本)当用户从csh中获取它们时,只需发送一条消息提醒用户使用bash而不是csh来运行它们。同时,我希望它们继续充当bash脚本


那么,是否有一些代码可以放在脚本的开头,这些代码在bash中是不可操作的,但当从cshell中获取时,会发出错误信号并取消文件其余部分的执行(但不会杀死shell本身)?

由于csh古老的变量替换风格,这比我想象的要困难。但是,
$?BASH_版本
在csh中扩展为0(未设置),在BASH中扩展为
0BASH_版本
(或最后一个命令的RV是什么)。所以

test "$?BASH_VERSION" = 0 && exit 1

我们应该做到这一点

这并不容易,因为不能以相同的方式分配变量或以相同的方式运行if语句

你可以使用csh微薄的字符串解析技巧来对付它自己。在我测试它的所有平台(Linux、AIX、HP-UX、Solaris)上,以下命令在所有shell中都可以干净地执行,包括KSH、BASH、ZSH、CSH和SH:

这里使用的想法是,反斜杠在CSH上的双引号字符串中并不特殊,而所有其他shell都认为它们是不同的

但是,这只是回答的一半,如果检测到“错误”的shell,您不想简单地退出脚本,那么您想做什么?嗯,您可能需要在脚本中添加一个Bournish
sh
部分和一个
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
),但刚才玩了一下,我发现
test-n“$BASH\u版本”| |…
打印了一条错误消息,但没有运行
。但好的一面是,我还发现
源代码
d脚本中的
退出
并没有杀死shell。(不知道为什么。)所以退出是一个很好的开始。@ruakh:不,对不起。我假设| | | | |
可以进入csh。@ruakh:
|
可以,但是变量替换杀死了我。编辑。看起来我们有赢家了!非常感谢!额外注意:只需将
=
更改为
!=/code>即可反转测试,因此这也可以用于“保护”csh脚本不被bash执行。感谢您提供了关于如何在单个脚本文件中嵌入(几乎)两个shell的任意代码的更一般的答案。
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 ...