Linux 检查文件是否存在[SH]

Linux 检查文件是否存在[SH],linux,bash,shell,if-statement,sh,Linux,Bash,Shell,If Statement,Sh,我创建了一个脚本,该脚本将检查基本目录中是否存在.gz文件,如果找到它们,它将根据当前日期将它们移动到一个新的结构中。当shell被设置为/bin/bash并且我手动运行它时,脚本工作得非常好,但是这个脚本是作为cron作业运行的(通过logrotate),我相信它必须在/bin/sh下运行,因为我不知道如何让logrotate在/bin/bash下运行它。有问题的代码是 # Move rotated logs to the archive if [ -f $BASEDIR/*.gz ]; th

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

# 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


任何帮助都会很棒

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

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”]
    测试此列表中的名字是否存在——如果存在,则我们知道扩展成功
    [-L“$1”]
    如果glob成功扩展,但第一个条目是指向不存在的文件的符号链接,则也可以为true;通过包含它,我们涵盖了那个角落的案例
  • mv--“$@”“$DIRECTORY”
    重用该参数列表以传递给
    mv
    --
    参数向
    mv
    指定以下所有参数都是名称,即使它们以
    -
    s开头
    • 这个怎么样:

      if ls "$BASEDIR"/*.gz
      then
          echo "moving them ..."
      else
          echo "No such file!"
      fi
      

      顺便说一句——所有大写名称都用于对OS或shell有意义的变量,而小写名称则保留给应用程序使用。请看@CharlesDuffy的第四段,谢谢你提供的信息,我从来都不知道这种区别,并且总是对全局可用的变量使用所有的大写。非常感谢。这就成功了,一切都很好!我发现有趣的是,单文件限制在bash中不是问题,但在sh中却是一个问题。在bash中也是一个问题——我想知道,如果ls“$BASEDRI”在早期测试时,您是否没有准备好传输多个文件?
      /*.gz&>/dev/null
      …我最初的回答中也包含了对输出的抑制,但后来我删除了它,因为它清晰明了,而且我觉得OP实际上可能想要这个输出。在else案例中已经有这样一个消息,我认为它在当时的案例中也很有用。当然,在大多数情况下,你提出的压制是标准的。