2

我认为 C shell 脚本的行为会像 C 一样,并对逻辑运算符使用短路评估。

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

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

我们在 C shell 脚本中有短路逻辑或吗?

4

2 回答 2

3

是的,&&并且||是 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 命令的全部输出存储在变量中并不是真正必要的。相反,您可以调用 find 并使用其返回的状态来告诉您它是否找到任何东西:

我刚试过这个:

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

它起作用了——除了>& /dev/null在大括号内似乎忽略了重定向。

相反,您可以单独执行“查找”命令,然后检查生成的 $status。这意味着您失去了短路||运算符的好处;您将不得不求助于嵌套if语句和/或临时变量。

也许真正的教训是:我使用 csh 和 tcsh 的年头比我愿意承认的要长,而我能够弄清楚很多这些东西的唯一方法是反复试验。您可以使用 tcsh 或 csh 执行此操作,但您可能最好使用不同的脚本语言。例如,在 Bourne shell 中,这相当简单:

if [ ! -e $cache ] || find $monitor -newer $cache >/dev/null 2>&1 ; then
    ...
fi
于 2011-07-24T01:35:36.003 回答
1

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

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

在这两种情况下, foo 都不会被淘汰。

但是,AFAIK 你不能像这样使用这种字符串比较,即使短路,csh 仍然会语法检查整个事情。

于 2010-09-12T08:08:50.083 回答