【问题标题】:check if file does not exist or is older than another in csh检查文件是否不存在或是否比 csh 中的另一个旧
【发布时间】:2016-04-10 06:31:20
【问题描述】:

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

谢谢!

【问题讨论】:

  • 我刚刚意识到 bash 命令的 if 语句中的第二个条件有多么错误,但它没有被执行所以没关系^^

标签: shell logical-operators csh tcsh


【解决方案1】:

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

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

如果您想要仍然可以理解的干净 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"

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

【讨论】:

  • 谢谢!这确实是一个干净的解决方案。对不起这个搞砸的例子。
【解决方案2】:

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

#!/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

【讨论】:

  • 当文件不存在时,这不会执行所需的命令(代码中的第二个 echo 1)。
  • 其实,OP 的 question 本身就是如何消除错误信息。如果我重写了 OP 的脚本,我可能会以不同的方式完成它(并且仍然按照 OP 的要求在一行中)。
猜你喜欢
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-08-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 2011-01-21
相关资源
最近更新 更多