1

I know this is a common question, but I do not understand how the solutions provided work. Everyone advises to change the date to seconds from the epoch and then divide by (24 * 3600) to get the difference in days. Or use

if [ $first_date -gt $second_date ]

However, what I don't understand is why no one notices the glaring mistake of using seconds from epoch in that they would differ even within a day. Or if you consider 5:30 pm of a specific day and 9:00 am of the next day, the difference between the seconds won't lead to a gap of 24 hours, and thus, they would be erroneously considered to be the same day.

My usage scenario is this: I need to purge logs that are older than a given number of days. Thus, my expiration_date, which I am forming after taking the user input of the number of days is:

expiration_date=$(date -d "-$1 day" + %s)

My file modification dates I am getting by using stat command as follows:

file_date=$( stat -c %Y $entry )

I need to compare these two dates and purge them if the file modification dates are "lesser than" the expiration date. Please help me in this regard.

EDIT

I am really confused as to the use of the mtime argument of the find command. Let's consider that we have the following files:

Nov15_1 Nov15_2 Nov17_1 Nov17_2 Nov18_1 Nov18_2 Nov19_1 Nov19_2

If I now run the find command using "0" as the mtime argument on Nov 19, it's giving me all the files except the first four.

find /dir/ -type f -mtime 0 -name "Nov*"

Nov18_1 Nov18_2 Nov19_1 Nov19_2

And if I run it using "+0", it's giving me only the first four files.

find /dir/ -type f -mtime +0 -name "Nov*"

Nov15_1 Nov15_2 Nov17_1 Nov17_2

If we express this using variables, saying that we want to purge logs from the nth day of the month and further back, and we run the command on the (n+1)th day using mtime as +0, which should translate to "1 day back and further", it's actually taking the files from the (n-1)th day and back, i.e. from "2 days back and further". Does this mean that there is no way to get just the files from 1 day back and further somehow? The argument of "0" is mixing it with today's files as well.

EDIT

So I incorporated the -daystart option as pointed out by @AdminBee, and results are as per my expectations. Now if I run the command on the (n+1)th day trying to remove the logs of the nth day and earlier, the command would be

 find /dir/ -type f -daystart -mtime +0 -name "Nov*"

Irrespective of whether the file modification timestamp is within the 24-hour period moving back from now, it will now consider the files of the previous day as being behind by 1 day, and will also list all other files previous to them.

  • 1
    You might be happy with the mtime option of find – Panki Nov 18 '19 at 10:20
  • 1
    unix.stackexchange.com/search?q=ddiff points to several possible duplicates – Stéphane Chazelas Nov 18 '19 at 10:28
  • 1
    "Or if you consider .... erroneously considered to be the same day" wouldn't they be considered different fractions of different days? – muru Nov 18 '19 at 10:29
  • "after taking the user input": how do you formulate that? Could not a user make a glaring mistake easily? – rastafile Nov 18 '19 at 16:38
  • "...nth day of the month..." I think you like to confuse yourself. – rastafile Nov 19 '19 at 7:24
1

You would probably need to provide more details on the actual use case. I assume you have a cleanup script running daily and want to remove all files older that, say, 5 days (so from 6 days ago or earlier).

Under these circumstances, you could combine the conditional file search and remove operation into one command by using find (here assuming GNU find or compatible), as in

find /start/of/logfile/dir/structure ! -type d -daystart -mtime +5 -delete

which if run at 2019-11-16 22:54:12 local time, would delete non-directory files whose last modification time is before 2019-11-11 00:00:00 (so files from the 10th and older).

Note that the -daystart option to this find command should achieve your desired behaviour. If you need restrict the operation to specific filename parts, you will have to add -name <pattern> (cf. the documentation to GNU find).

Also note that depending on the version of find installed on your machine, the -delete operation may not be available, so you may have to use -exec rm {} \; instead.

  • So, from your example, I have the feeling that if I have to purge logs from n number of days back and further, I will have to give the argument to mtime as +(n-1). Please correct me if I'm wrong. – abhishek Nov 18 '19 at 11:13
  • Yes, I believe you are right, and my own tests support that. I would still recommend to err on the safe side and test "non-destructively" if the filter rules do exactly what you intend. – AdminBee Nov 18 '19 at 11:52
  • @Stéphane Chazelas good point updating the filter rules, thanks you! – AdminBee Nov 18 '19 at 11:53
  • Please take a look at the edit of my question which I posted after testing the command. – abhishek Nov 19 '19 at 7:00
  • 1
    @abhishek glad to hear it! – AdminBee Nov 19 '19 at 10:37
0

man find, -atime:

...so to match -atime +1, a file has to have been accessed at least two days ago.

Option -daystart changes the interpretation:

-daystart
 Measure times (for -amin, -atime, -cmin, -ctime, -mmin, and  -mtime)
 from the beginning of today rather than from 24 hours ago.  

touch -d '2019-11-19 0800' thismorning lets you easily create testfiles:

]# find -name '*n*g*' -daystart -mtime 0 -ls 
      Nov 19 08:00 ./thismorning
]# find -name '*n*g*' -daystart -mtime 1 -ls 
      Nov 18 22:30 ./lastnight
      Nov 18 08:30 ./lastmorning
]# find -name '*n*g*'  -mtime 0 -ls 
      Nov 18 22:30 ./lastnight
      Nov 19 08:00 ./thismorning
]# find -name '*n*g*'  -mtime 1 -ls 
      Nov 17 22:00 ./lastlastnight
      Nov 18 08:30 ./lastmorning

(I snipped away -ls output fields -- only left the dates and filenames)

]# find -name '*n*g*'; date         
./lastnight
./thismorning
./lastlastnight
./lastmorning
Tue Nov 19 10:34:33 UTC 2019
]# find -name '*n*g*' -daystart -mtime 2 -ls 
   Nov 17 22:00 ./lastlastnight
]# 

...because you mix up calender days and 24h-periods in your OP. Sometimes we want this, sometimes that.

Why seconds since epoch?

If you want to know how long something lasted, i.e. the difference of two dates, our calender has these irregularities (the months). So either use your knuckles, know about emperors Julius and Augustus, or use brute force via seconds.

From 30.7. to 1.9. is three days longer than 30.1. to 1.3., and it even depends on leap years.

today, 5:30 pm and tomorrow 6:00 am are

  • different days (calendar wise)
  • only half a day apart (day=duration of 24x60x60 seconds)

From your expiration_date I deduct you want to count the 24h periods passed. That means at 1:00am most of "yesterday" is unaffected.

I tested and correted the date command

]# date -d "-1 day" +%s
1574003538
]# date -d "-0 day" +%s
1574089945

The difference is 86407 i.e 24x60x60.

(And if somebodey asks me: "What were you doing at date -d @1574089945?" I can say: "I was editing a command for seven seconds")


]# find . -atime 1
./here.sh
]# find . -atime +0 -atime -2
./here.sh
]# ls -l here.sh 
-rw-r--r-- 1 root root 154 Nov 16 21:37 here.sh

Now is Nov 18 16:43. So there is one full 24h period between.

  • From your example, I can understand that as the file had been accessed a little more than 24 hours ago, it came up in +0. So, please explain this to me once and for all: does find consider the hours gap for considering whether a file is more than a day old? Or does it consider calendar days? And what would I do if my use case was for calendar days (which it is), not the difference in hours? – abhishek Nov 19 '19 at 7:44
  • @abhishek I added the -daystart definition of man find. I did not test or meditate on that, but this must be it. Still: think about how to translate that into a user prompt / natural language. Do you throw away yesterday's paper at 00:20 am? (you can, but it needs clear definitions). – rastafile Nov 19 '19 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.