CシェルスクリプトはCのように動作し、論理演算子に短絡評価を使用すると思いました。
if ((! -e $cache ) || ("`find $monitor -newer $cache`" != "")) then
...
endif
しかし、ifステートメントでは、最初の条件が真であっても、2番目の条件がチェックされてエラーが発生します。
Cシェルスクリプトに論理和の短絡がありますか?
CシェルスクリプトはCのように動作し、論理演算子に短絡評価を使用すると思いました。
if ((! -e $cache ) || ("`find $monitor -newer $cache`" != "")) then
...
endif
しかし、ifステートメントでは、最初の条件が真であっても、2番目の条件がチェックされてエラーが発生します。
Cシェルスクリプトに論理和の短絡がありますか?
はい、&&
そして||
tcshの短絡演算子です(Cの場合と同じです)。また、2つの異なる形式があります。1つはコマンド(のようにfalse && echo foo
)で機能し、もう1つは式(のように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シェルでは、これはかなり簡単です。
if [ ! -e $cache ] || find $monitor -newer $cache >/dev/null 2>&1 ; then
...
fi
通常、&&
および||
は短循環です。次のようなことを考えてみてください。
$ false && echo foo
$ true || echo foo
どちらの場合も、fooは出されません。
しかし、AFAIKでは、このような文字列比較をこのように使用することはできません。たとえ短絡したとしても、cshは全体を構文チェックします。