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

时间:2016-01-06 08:22:54

标签: shell logical-operators csh tcsh

在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中实现此行为的任何想法?我不希望命令在我的代码中执行两次。

谢谢!

2 个答案:

答案 0 :(得分:3)

CSH有一个解析器,说实话,并不值得这个名字。

在这个特定情况下的问题是它没有评估||的左侧在开始stat之前先构建(正如您所见)。由于您依赖于stat的标准输出,您也无法通过>& /dev/null重定向输出,而仅重新定向stderr有点令人讨厌(请参阅{{3} })。

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

#!/bin/csh
set f=$1
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"

(请注意,您的原始代码的年龄测试也与您的散文相反。)

答案 1 :(得分:0)

您可以在shell命令中移动-f测试,您可以从中重定向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