如何编写脚本以确定文件在/ bin / sh中是否超过30分钟?
不幸的是,系统中不存在统计数据。它是一个古老的Unix系统,http://en.wikipedia.org/wiki/Interactive_Unix
遗憾的是,Perl没有安装在系统上,客户也不想安装它,也没有其他任何东西。
这是使用find
的一种方式。
if test "`find file -mmin +30`"
如果相关文件包含空格或特殊字符,则必须引用find
命令。
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi
这是我对find
的变化:
if [ `find cache/nodes.csv -mmin +10 | egrep '.*'` ]
查找始终返回状态代码0
,除非它失败;然而,egrep
返回1
是找不到匹配。因此,如果该文件超过10分钟,则此组合将通过。
试试吧:
touch /tmp/foo; sleep 61;
find /tmp/foo -mmin +1 | egrep '.*'; echo $?
find /tmp/foo -mmin +10 | egrep '.*'; echo $?
应该在文件路径后打印0然后再打印1。
我的功能使用这个:
## Usage: if isFileOlderThanMinutes "$NODES_FILE_RAW" $NODES_INFO_EXPIRY; then ...
function isFileOlderThanMinutes {
if [ "" == "$1" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
if [ "" == "$2" ] ; then serr "isFileOlderThanMinutes() usage: isFileOlderThanMinutes <file> <minutes>"; exit; fi
## Does not exist -> "older"
if [ ! -f "$1" ] ; then return 0; fi
## The file older than $2 is found...
find "$1" -mmin +$2 | egrep '.*' > /dev/null 2>&1;
if [ $? == 0 ] ; then return 0; fi ## So it is older.
return 1; ## Else it not older.
}
以下为您提供以秒为单位的文件年龄:
echo $(( `date +%s` - `stat -L --format %Y $filename` ))
这意味着对于超过30分钟的文件,这应该给出真/假值(1/0):
echo $(( (`date +%s` - `stat -L --format %Y $filename`) > (30*60) ))
30*60
- 一分钟60秒,不预先计算,让CPU为你工作!
如果你正在写一个sh脚本,最有用的方法是使用test
和已经提到的stat技巧:
if [ `stat --format=%Y $file` -le $(( `date +%s` - 1800 )) ]; then
do stuff with your 30-minutes-old $file
fi
请注意,[
是test
的符号链接(或其他等价物);请参阅man test
,但请记住,test
和[
也是bash内置因素,因此行为略有不同。 (另请注意[[
bash复合命令)。
好的,没有统计数据和残缺的发现。这是您的替代方案:
编译GNU coreutils以获得一个不错的发现(以及许多其他方便的命令)。你可能已经把它当作gfind了。
如果date
工作,也许你可以使用-r
获取文件修改时间?
(`date +%s` - `date -r $file +%s`) > (30*60)
或者,使用-nt
比较来选择哪个文件更新,麻烦的是在过去30分钟制作一个mod时间的文件。 touch
通常可以做到这一点,但所有赌注都取消了。
touch -d '30 minutes ago' 30_minutes_ago
if [ your_file -ot 30_minutes_ago ]; then
...do stuff...
fi
最后,看看Perl是否可用而不是与谁知道谁知道shell实用程序的版本。
use File::stat;
print "Yes" if (time - stat("yourfile")->mtime) > 60*30;
对于像我这样的人,根据@slebetman的回答,不喜欢背蜱:
echo $(( $(date +%s) - $(stat -L --format %Y $filename) > (30*60) ))
您可以通过与使用30分钟前的时间戳创建的参考文件进行比较来完成此操作。
首先通过输入创建比较文件
touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago
用30分钟前的值替换时间戳。您可以使用Perl中的一个简单的一个线程来自动执行此步骤。
然后使用find的较新运算符来通过否定搜索运算符来匹配较旧的文件
find . \! -newer /tmp/thirty_minutes_ago -print
你的意思是超过30分钟:超过30分钟前修改,或超过30分钟前创建?希望它是前者,因为到目前为止的答案对于这种解释是正确的。在后一种情况下,由于unix文件系统不跟踪文件的创建时间,因此存在问题。 (当inode内容最后一次更改时,ctime
文件属性会记录,例如chmod
或chown
发生的事情)。
如果你真的需要知道文件是否是在30多分钟前创建的,你要么必须用find
重复扫描文件系统的相关部分,要么使用像linux的inotify这样的平台依赖。
#!/usr/bin/ksh
## this script creates a new timer file every minute and renames all the previously created timer files and then executes whatever script you need which can now use the timer files to compare against with a find. The script is designed to always be running on the server. The first time the script is executed it will remove the timer files and it will take an hour to rebuild them (assuming you want 60 minutes of timer files)
set -x
# if the server is rebooted for any reason or this scripts stops we must rebuild the timer files from scratch
find /yourpath/timer -type f -exec rm {} \;
while [ 1 ]
do
COUNTER=60
COUNTER2=60
cd /yourpath/timer
while [ COUNTER -gt 1 ]
do
COUNTER2=`expr $COUNTER - 1`
echo COUNTER=$COUNTER
echo COUNTER2=$COUNTER2
if [ -f timer-minutes-$COUNTER2 ]
then
mv timer-minutes-$COUNTER2 timer-minutes-$COUNTER
COUNTER=`expr $COUNTER - 1`
else
touch timer-minutes-$COUNTER2
fi
done
touch timer-minutes-1
sleep 60
#this will check to see if the files have been fully updated after a server restart
COUNT=`find . ! -newer timer-minutes-30 -type f | wc -l | awk '{print $1}'`
if [ $COUNT -eq 1 ]
then
# execute whatever scripts at this point
fi
done