C shell 脚本中是否有短路逻辑运算符?

发布于 2024-09-18 13:50:43 字数 226 浏览 8 评论 0原文

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

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

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

C shell 脚本中是否有短路逻辑或?

I thought C shell script will behave like C and use short circuit evaluation for logical operators.

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

But in the if statement, even if the first condition is true, the second is checked giving me errors.

Do we have a short circuit logical OR in C shell script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谎言 2024-09-25 13:50:43

是的,&&|| 是 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 重定向似乎在大括号内被忽略。

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

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

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

Yes, && and || are short-circuit operators in tcsh (just as they are in C). And there are two distinct forms, one that works on commands (as in false && echo foo), and one that works on expression (as in if (-e $file1 && -e $file2)).

I'm not entirely sure what's going on here, except that csh and tcsh are notorious for ill-defined syntax. A bit of experimentation shows that saving the output of find in a variable avoids the error:

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

(Note that the extra parentheses aren't really necessary, but they don't hurt anything.)

But more improvement is possible. Storing the entire output of the find command in a variable isn't really necessary. Instead, you can invoke find and use its returned status to tell you whether it found anything:

I just tried this:

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

and it worked -- except that the >& /dev/null redirection seems to be ignored within the braces.

Instead, you can execute the "find" command separately, and then examine the resulting $status. Which means that you lose the benefit of the short-circuit || operator; you'll have to resort to nested if statements and/or temporary variables.

Perhaps the real lesson is this: I've been using csh and tcsh for more years than I care to admit, and the only way I was able to figure out a lot of this stuff was by trial and error. You can do this using tcsh or csh, but you're probably better of using a different scripting language. For example, in Bourne shell, this is fairly straightforward:

if [ ! -e $cache ] || find $monitor -newer $cache >/dev/null 2>&1 ; then
    ...
fi
梦境 2024-09-25 13:50:43

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

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

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

但是,据我所知,您不能像这样使用这种字符串比较,即使短路,csh 仍然会对整个事情进行语法检查。

Usually, &&and || are short-circut. Consider something like this:

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

In both cases, foo won't be put out.

But, AFAIK you cannot use this kind of string comparison like this, even if short-circuit, csh will still syntax-check the whole thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文