我们在C shell脚本中有短路逻辑运算符吗?

时间:2010-09-12 08:04:04

标签: scripting shell csh tcsh short-circuiting

我认为C shell脚本的行为与C类似,并对逻辑运算符使用短路评估。

if ((! -e $cache ) || ("`find $monitor -newer $cache`" != "")) then
...
endif

但是在if语句中,即使第一个条件为真,也会检查第二个条件是否给我错误。

我们在C shell脚本中是否有短路逻辑OR?

2 个答案:

答案 0 :(得分:2)

是的,&&||是tcsh中的短路运算符(就像它们在C中一样)。并且有两种不同的形式,一种适用于命令(如false && echo foo),另一种适用于表达(如if (-e $file1 && -e $file2))。

我不完全确定这里发生了什么,除了csh和tcsh因语法错误而臭名昭着。一些实验表明,在变量中保存find的输出可以避免错误:

set s = "`find $monitor -newer $cache`"
if ((! -e $cache) || ("$s" != "")) then
    echo ok
endif

(请注意,额外的括号不是必需的,但它们不会伤害任何东西。)

但是可以进一步改进。将find命令的整个输出存储在变量中并不是必需的。相反,您可以调用查找并使用其返回的状态来告诉您它是否找到了任何内容:

我刚试过这个:

if (! -e $cache || { find $monitor -newer $cache >& /dev/null } ) then
    echo ok
endif

并且它有效 - 除了>& /dev/null重定向似乎在大括号内被忽略。

相反,您可以单独执行“find”命令,然后检查生成的$ status。这意味着您将失去短路||运营商的利益;你必须求助于嵌套的if语句和/或临时变量。

也许真正的教训是这样的:我一直在使用csh和tcsh多年,而不是我承认,并且我能够找出很多这些东西的唯一方法是通过反复试验。您可以使用tcsh或csh执行此操作,但您最好使用其他脚本语言。例如,在Bourne shell中,这非常简单:

if [ ! -e $cache ] || find $monitor -newer $cache >/dev/null 2>&1 ; then
    ...
fi

答案 1 :(得分:1)

通常,&&||是短路的。考虑这样的事情:

$ false && echo foo
$ true || echo foo

在这两种情况下,foo都不会被推出。

但是,AFAIK你不能像这样使用这种字符串比较,即使短路,csh仍会对语法进行语法检查。