48

如何编写脚本来确定 /bin/sh 中的文件是否超过 30 分钟?

不幸的是,系统中不stat存在该命令。它是一个旧的 Unix 系统,http ://en.wikipedia.org/wiki/Interactive_Unix

不幸的是,Perl 没有安装在系统上,客户也不想安装它,也不想安装它。

4

12 回答 12

78

这是使用find.

if test "`find file -mmin +30`"

find如果相关文件包含空格或特殊字符,则必须引用该命令。

于 2010-01-05T09:30:44.323 回答
34

以下以秒为单位为您提供文件年龄:

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为你做事!

于 2010-01-05T09:30:20.497 回答
24

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).

于 2010-01-05T11:24:56.203 回答
12

好的,没有统计数据和残缺的发现。这是您的替代方案:

编译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;
于 2010-01-05T13:55:55.090 回答
5

对于像我这样不喜欢反勾号的人,根据@slebetman 的回答:

echo $(( $(date +%s) - $(stat -L --format %Y $filename) > (30*60) ))
于 2015-02-24T22:20:42.223 回答
3

您可以通过与您创建的具有三十分钟前时间戳的参考文件进行比较来做到这一点。

首先通过输入创建您的比较文件

touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago

用三十分钟前的值替换时间戳。您可以使用 Perl 中的一个简单的单行来自动执行此步骤。

然后使用 find 的 newer 运算符通过否定搜索运算符来匹配较旧的文件

find . \! -newer /tmp/thirty_minutes_ago -print
于 2010-01-05T09:55:01.783 回答
2

超过 30 分钟是什么意思:修改时间超过 30 分钟,还是创建时间超过 30 分钟?希望是前者,因为到目前为止的答案对于这种解释是正确的。在后一种情况下,您会遇到问题,因为 unix 文件系统不跟踪文件的创建时间。(ctime文件属性记录inode内容上次更改的时间,即类似chmodchown发生的事情)。

如果您真的需要知道文件是否是在 30 分钟前创建的,您要么必须使用类似的东西反复扫描文件系统的相关部分,find要么使用依赖于平台的东西,如 linux 的inotify

于 2010-01-05T09:57:20.297 回答
2
#!/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
于 2011-06-07T19:42:34.843 回答
2

您可以使用查找命令。
例如,要搜索当前目录中超过 30 分钟的文件:

find . -type f -mmin +30 

您可以在此处阅读有关find命令的信息

于 2017-10-13T07:27:11.843 回答
2

这是我的变化find

if [ `find cache/nodes.csv -mmin +10 | egrep '.*'` ]

Find 总是返回状态码0,除非它失败;但是,egrepreturns 1is 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.
}
于 2018-03-02T01:41:28.963 回答
2

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
于 2020-09-28T18:21:09.873 回答
0
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi
于 2017-05-23T00:14:40.187 回答