关于linux:检查文件是否存在[SH]

Check if file exists [SH]

本问题已经有最佳答案,请猛点这里访问。

我创建了一个脚本,该脚本将检查基目录中是否存在.gz文件,如果找到这些文件,它会根据当前日期将它们移动到新的结构中。当shell设置为/bin/bash并且我手动运行它时,脚本工作得很好,但是这个脚本作为cron作业(通过logrotate)运行,我相信它必须在/bin/sh下运行,因为我不知道如何让logrotate在/bin/bash下运行它。所讨论的代码是

1
2
3
4
5
6
7
8
# Move rotated logs to the archive
if [ -f $BASEDIR/*.gz ]; then
        logger"$SNAME Moving rotated logs to $DIRECTORY"
        mv $BASEDIR/*.gz $DIRECTORY
else
        echo"$BASEDIR/*.gz"
        logger"$SNAME No rotated logs to move. Is this normal?"
fi

在bash中,条件检查非常有效,在sh中它抱怨有太多的参数。如果我把东西放在引号中,它不会看到通配符,aways返回false。

任何帮助都会很棒!


这个怎么样?

1
2
3
4
5
6
if ls"$BASEDIR"/*.gz
then
    echo"moving them ..."
else
    echo"No such file!"
fi


这里的问题是,[ -f pathname ]只取一个名称([ -f one.gz two.gz ]不是有效的test语法),但您不知道*.gz扩展到多少个名称。

1
2
3
4
5
6
7
8
9
10
11
check() {
  set --"$BASEDIR"/*.gz
  if [ -f"$1" ] || [ -L"$1" ]; then
    logger"$SNAME Moving rotated logs to $DIRECTORY"
    mv --"$@""$DIRECTORY"
  else
    echo"$BASEDIR/*.gz"
    logger"$SNAME No rotated logs to move. Is this normal?"
  fi
}
check

分解:

  • check() { ... }定义了一个名为check的函数,我们随后调用它。
  • set --"$BASEDIR"/*.gz替换了函数的参数列表(这就是我们使用函数的原因,所以我们不会覆盖整个脚本的参数列表!)文件名以*.gz结尾。
  • [ -f"$1" ]测试这个列表中的名字是否存在——如果存在,那么我们就知道扩展是成功的。如果glob成功扩展,那么[ -L"$1" ]也可以是真的,但第一个条目是指向不存在的文件的符号链接;通过包含它,我们可以覆盖这个角落的情况。
  • mv --"$@""$DIRECTORY"重用该参数列表传递给mv--参数向mv指定以下所有参数都是名称,即使它们以-开头。