如何编写脚本来确定 /bin/sh 中的文件是否超过 30 分钟?
不幸的是,系统中不stat
存在该命令。它是一个旧的 Unix 系统,http ://en.wikipedia.org/wiki/Interactive_Unix
不幸的是,Perl 没有安装在系统上,客户也不想安装它,也不想安装它。
如何编写脚本来确定 /bin/sh 中的文件是否超过 30 分钟?
不幸的是,系统中不stat
存在该命令。它是一个旧的 Unix 系统,http ://en.wikipedia.org/wiki/Interactive_Unix
不幸的是,Perl 没有安装在系统上,客户也不想安装它,也不想安装它。
这是使用find
.
if test "`find file -mmin +30`"
find
如果相关文件包含空格或特殊字符,则必须引用该命令。
以下以秒为单位为您提供文件年龄:
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为你做事!
If you're writing a sh script, the most useful way is to use test
with the already mentioned stat trick:
if [ `stat --format=%Y $file` -le $(( `date +%s` - 1800 )) ]; then
do stuff with your 30-minutes-old $file
fi
Note that [
is a symbolic link (or otherwise equivalent) to test
; see man test
, but keep in mind that test
and [
are also bash builtins and thus can have slightly different behavior. (Also note the [[
bash compound command).
好的,没有统计数据和残缺的发现。这是您的替代方案:
编译GNU coreutils以获得一个不错的发现(以及许多其他方便的命令)。您可能已经将其作为 gfind。
如果可行,也许您可以使用它date
来获取文件修改时间-r
?
(`date +%s` - `date -r $file +%s`) > (30*60)
或者,使用-nt
比较来选择哪个文件较新,麻烦的是制作一个具有过去 30 分钟修改时间的文件。 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) ))
您可以通过与您创建的具有三十分钟前时间戳的参考文件进行比较来做到这一点。
首先通过输入创建您的比较文件
touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago
用三十分钟前的值替换时间戳。您可以使用 Perl 中的一个简单的单行来自动执行此步骤。
然后使用 find 的 newer 运算符通过否定搜索运算符来匹配较旧的文件
find . \! -newer /tmp/thirty_minutes_ago -print
超过 30 分钟是什么意思:修改时间超过 30 分钟,还是创建时间超过 30 分钟?希望是前者,因为到目前为止的答案对于这种解释是正确的。在后一种情况下,您会遇到问题,因为 unix 文件系统不跟踪文件的创建时间。(ctime
文件属性记录inode内容上次更改的时间,即类似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
这是我的变化find
:
if [ `find cache/nodes.csv -mmin +10 | egrep '.*'` ]
Find 总是返回状态码0
,除非它失败;但是,egrep
returns 1
is no match is found`。因此,如果该文件早于 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.
}
myfile.txt的当前时间和上次修改时间之间的秒差:
echo $(($(date +%s)-$(stat -c "%Y" myfile.txt)))
您也可以使用%X
或%Z
与命令stat -c
来获取上次访问或上次状态更改之间的差异,检查 0 返回!
%X time of last access, seconds since Epoch
%Y time of last data modification, seconds since Epoch
%Z time of last status change, seconds since Epoch
考试:
if [ $(($(date +%s)-$(stat -c "%Y" myfile.txt))) -lt 600 ] ; then echo younger than 600 sec ; else echo older than 600 sec ; fi
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi