检查文件是否不存在或比 csh 中的另一个文件旧

check if file does not exist or is older than another in csh

in C-shell 我需要检查一个文件是否存在或者它是否比另一个文件早(或者在这个例子中从 unix 时间开始时早于 5 秒)。如果文件不存在或者是旧的,一些东西应该被执行。

在我的例子中"bla.txt"不存在,所以第一个条件为真

if ( ! -f bla.txt || `stat -c "%Y" bla.txt` > 5 ) echo 1
stat: cannot stat `bla.txt': No such file or directory
1

问题是,如果我将这些条件组合在一个 if 语句中,第二个条件(文件的年龄)会被执行,尽管第一个条件已经为真并给出错误,因为文件不存在。

在 bash 中,一切正常

if [ ! -f bla.txt ] || [ `stat -c "%Y" bla.txt` > 5 ]; then echo 1; fi
1

关于如何在没有 else if 的情况下在 csh 中实现此行为的任何想法?我不想让命令在我的代码中执行两次。

谢谢!

您可以将 -f 测试移动到 shell 命令中,您从中重定向 stat 的输出。这里有一个脚本来说明:

#!/bin/csh                                                                 
set verbose
set XX=/tmp/foo
set YY=2
rm -f $XX
foreach ZZ ( 0 1 )
    if ( ` stat -c "%Y" $XX` > $YY ) echo 1
    if ( ` test -f $XX && stat -c "%Y" $XX` > $YY ) echo 1
    if ( $ZZ == 0 ) touch $XX
    stat -c "%Y" $XX
    sleep $YY
end

CSH 有一个解析器,老实说,它名不副实。

此特定实例中的问题是它不计算 || 的左侧在开始 stat 之前首先构建(如您所见)。由于您依赖于 stat 的标准输出,您也不能通过 >& /dev/null 重定向输出,并且仅 stderr 的重定向有点麻烦(请参阅 )。

如果您想要仍然可以理解的干净的 csh 代码,但不想编写两次实际代码调用,我认为最干净的解决方案是使用中间变量。像这样:

#!/bin/csh
set f=
set do=0
if ( ! -f $f ) then
  set do=1
else
  if ( `stat -c "%Y" $f >& /dev/null ` < 5 ) set do=1
endif

if ( $do ) echo "File $f does not exist or is older than 5s after epoch"

(请注意,您的原始代码还对您的散文进行了年龄测试。)