web-dev-qa-db-ja.com

ファイルが/ bin / shから30分以上経過しているかどうかを確認するにはどうすればよいですか?

/ bin/shでファイルが30分以上経過しているかどうかを判断するスクリプトを作成するにはどうすればよいですか?

残念ながら、statコマンドはシステムに存在しません。古いUnixシステム http://en.wikipedia.org/wiki/Interactive_Unix

残念ながら、Perlはシステムにインストールされておらず、顧客はそれをインストールすることを望んでおらず、他にも何もありません。

38
magol

findを使用する1つの方法を次に示します。

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

問題のファイルにスペースまたは特殊文字が含まれている場合は、findコマンドを引用符で囲む必要があります。

67
Schwern

以下は、ファイルの経過時間を秒単位で示します。

echo $(( `date +%s` - `stat -L --format %Y $filename` ))

つまり、これは30分以上経過したファイルに対してtrue/false値(1/0)を提供する必要があることを意味します。

echo $(( (`date +%s` - `stat -L --format %Y $filename`) > (30*60) ))

30*60-1分で60秒、事前計算せずに、CPUに作業を任せてください!

28
slebetman

Shスクリプトを作成している場合、最も便利な方法は、既に述べたstatトリックでtestを使用することです。

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複合コマンドにも注意してください)。

16
alvherre

わかりました、統計情報と障害のある検索。代替手段は次のとおりです。

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

最後に、Shellユーティリティのどのバージョンを誰が知っているかと格闘するのではなく、Perlが利用可能かどうかを確認します。

use File::stat;
print "Yes" if (time - stat("yourfile")->mtime) > 60*30;
9
Schwern

@slebetmanの回答に基づいて、バックティックが好きではない私のような人のために:

echo $(( $(date +%s) - $(stat -L --format %Y $filename) > (30*60) ))
5

これを行うには、30分前のタイムスタンプで作成した参照ファイルと比較します。

最初に入力して比較ファイルを作成します

touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago

タイムスタンプを30分前の値に置き換えます。 Perlのささいな1つのライナーを使用して、このステップを自動化できます。

次に、findのnewer演算子を使用して、検索演算子を否定することにより古いファイルを一致させます

find . \! -newer /tmp/thirty_minutes_ago -print
4
Rob Wells

Findコマンドを使用できます。
たとえば、現在のディレクトリで30分以上経過したファイルを検索するには:

find . -type f -mmin +30 

findコマンドについて読むことができます [〜#〜] here [〜 #〜]

2
mighty_mike

30分以上前30分以上前に変更された、または30分以上前に作成された?うまくいけば前者であり、これまでの答えはその解釈に対して正しいためです。後者の場合、UNIXファイルシステムはファイルの作成時間を追跡しないため、問題が発生します。 (ctimeファイル属性は、inodeの内容が最後に変更されたとき、つまりchmodchownが発生しました)。

ファイルが30分以上前に作成されたかどうかを本当に知る必要がある場合は、findのようなものでファイルシステムの関連部分を繰り返しスキャンするか、Linuxのようなプラットフォーム依存のものを使用する必要があります- inotify

2
Dale Hagglund
#!/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
2
dderton

findのバリエーションは次のとおりです。

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

Findは、失敗しない限り、常にステータスコード0を返します。ただし、egrep1が返されますが、一致が見つかりません。したがって、この組み合わせは、そのファイルが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.
}
0
Ondra Žižka
if [[ "$(date --rfc-3339=ns -r /tmp/targetFile)" < "$(date --rfc-3339=ns --date '90 minutes ago')" ]] ; then echo "older"; fi
0
user8050735