Linux 检查文件是否存在[SH]
我创建了一个脚本,该脚本将检查基本目录中是否存在.gz文件,如果找到它们,它将根据当前日期将它们移动到一个新的结构中。当shell被设置为/bin/bash并且我手动运行它时,脚本工作得非常好,但是这个脚本是作为cron作业运行的(通过logrotate),我相信它必须在/bin/sh下运行,因为我不知道如何让logrotate在/bin/bash下运行它。有问题的代码是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
# 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”]
如果glob成功扩展,但第一个条目是指向不存在的文件的符号链接,则也可以为true;通过包含它,我们涵盖了那个角落的案例[-L“$1”]
重用该参数列表以传递给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案例中已经有这样一个消息,我认为它在当时的案例中也很有用。当然,在大多数情况下,你提出的压制是标准的。