views:

805

answers:

6

How do I write a script to determine if a file is older than 30 minutes in /bin/sh?

Unfortunately does not stat exist in the system. It is an old Unix system, http://en.wikipedia.org/wiki/Interactive_Unix

Perl is unfortunately not installed on the system and the customer does not want to install it, and nothing else either.

+2  A: 

The following gives you the file age in seconds:

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

which means this should give a true/false value (1/0) for files older than 30 minutes:

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

30*60 -- 60 seconds in a minute, don't precalculate, let the CPU do the work for you!

slebetman
+7  A: 

Here's one way using find.

if test `find file -mmin +30`
Schwern
+1 for succinctness
slebetman
find does not have -mmin in Interactive Unix :-(
magol
A: 

G'day,

You can do this by comparing to a reference file that you've created with a timestamp of thirty minutes ago.

First create your comparison file by entering

touch -t YYYYMMDDhhmm.ss /tmp/thirty_minutes_ago

replacing the timestamp with the value thirty minutes ago. You could automate this step with a trivial one liner in Perl.

Then use find's newer operator to match files that are older by negating the search operator

find . \! -newer /tmp/thirty_minutes_ago -print

HTH

Rob Wells
newer works. But what do \! mean?How do I get the time 30 minutes ago in \bin\sh?
magol
@magol, just subtract it, e.g. I'm writing this at 17:22 on 5/1/2010 so the command for the "thirty minutes ago" file is touch -t 201001051652.00 /tmp/thirty_minutes_ago. Or you could use a Perl one liner to calculate it. The "\!" means not for the find command so "not newer" is older. HTH
Rob Wells
Does Interactive Unix happen to have Tcl? It has good date handling routines.
mpez0
Eliminating the Perl:time_now=`date +%s`time_then=`expr $time_now - 1800`time_file=`date -r <filename> +%s`if $time_then -gt $time_file; then echo "<filename> is more than 30 minutes old"; else echo "<filename> is less than 30 minutes old"; fi(untested, but should be close enough. Insert returns; I can't format the comment)
mpez0
A: 

What do you mean by older than 30 minutes: modified more than 30 minutes ago, or created more than 30 minutes ago? Hopefully it's the former, as the answers so far are correct for that interpretation. In the latter case, you have problems since unix file systems do not track the creation time of a file. (The ctime file attribute records when the inode contents last changed, ie, something like chmod or chown happened).

If you really need to know if file was created more than 30 minutes ago, you'll either have to scan the relevant part of the file system repeatedly with something like find or use something platform-dependent like linux's inotify.

Dale Hagglund
A: 

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

alvherre
Unfortunately does 'stat' not exist in the system :-(It is an old Unix system
magol
A: 

Ok, no stat and a crippled find. Here's your alternatives:

Compile the GNU coreutils to get a decent find (and a lot of other handy commands). You might already have it as gfind.

Maybe you can use date to get the file modification time if -r works?

(`date +%s` - `date -r $file +%s`) > (30*60)

Alternatively, use the -nt comparision to choose which file is newer, trouble is making a file with a mod time 30 minutes in the past. touch can usually do that, but all bets are off as to what's available.

touch -d '30 minutes ago' 30_minutes_ago
if [ your_file -ot 30_minutes_ago ]; then
    ...do stuff...
fi

And finally, see if Perl is available rather than struggling with who knows what versions of shell utilities.

use File::stat;
print "Yes" if (time - stat("yourfile")->mtime) > 60*30;
Schwern
bourne does not have -nt , -ot tests, does it?
ghostdog74
"date -r" does not work. "touch -d" does not work. But I can set time if I give exact time. But How do I get the time 30 minutes ago? I can't use Perl
magol
@magol `date -d '30 minutes ago' +%s` will give you the time 30 minutes ago.
Schwern
@ghostdog74 I guess I'm looking at bash not sh. I haven't seen a real Bourne Shell in years.
Schwern