0

I'd like to know how i can get all the files of type *x which were modified by an user after a number of days in the past. The positional parameters would be:

  • Directory where to search
  • Name of the user who modified the files
  • The number of days

The best option I figured out for now is:

#!/bin/bash

if [ $# -ne 3 ]; then
  echo "3 parameters needed, use ./script.sh path user days"
  exit
else
  find $1 -user $2 -type f -name \*x -mtime -$3 -print 2>&1 | grep -v "Permission denied"
fi

But it does not seem to work and see for users that modify files other than the current one, even though they have permission to the files.

mtnezm
  • 1,009
  • 1
  • 7
  • 19
thhhhhhhh
  • 7
  • 5
  • If you aren't running auditd or such (https://www.cyberciti.biz/tips/linux-audit-files-to-see-who-made-changes-to-a-file.html), you won't be able to tell which files were modified by a user. Without auditd, you still can find files modified in the last few days (https://stackoverflow.com/questions/16085958/find-the-files-that-have-been-changed-in-last-24-hours). – zedfoxus May 25 '20 at 19:49
  • What is the output you are getting when running that script? That `find` query seems to work for me. What user are you running it with? Does it have read permissions over the directories and files you specify in the path? – mtnezm Jun 07 '20 at 22:05

1 Answers1

1

Actually find provides the -newerXY option where XY is a reference made up of any of the following:

    a   The access time of the file reference
    B   The birth time of the file reference
    c   The inode status change time of reference
    m   The modification time of the file reference
    t   reference is interpreted directly as a time

(see: man 1 find)

To find files with a modification time before a given time you simply negate the -newermt "date" option, e.g. ! -newermt "date" (where date is in a format accepted by the date utiliity, -- yyyy-mm-dd or yyyy-mm-dd HH:MM:ss are fine)

Putting your pieces together, you could use:

## find files below dir for user modified before "date_given"
find "$1" -user "$2" ! -newermt "$3"

or

## find files below dir for user modified after "date_given"
find "$1" -user "$2" -newermt "$3"

or

## find files below dir for user modified since "days ago given"
find "$1" -user "$2" -newermt $(date -d "$3 days ago" +%F)

Your use of -mtime is also fine, though not quite as flexible. So long as you just want to know whether the files were modified within "days given" 24 hour periods ago, it will work fine:

## find files below dir for user modified within days given * 24 hour periods
find "$1" -user "$2" -mtime "-$3"

Adding minimal validations for a complete script presuming you want to validate each aspect before invoking find, you could do:

#!/bin/bash

[ "$#" -ne 3 ] && { ## validate 3 arguments given
    printf "error: insufficient arguments\nusage: %s dir user yyyy-mm-dd\n" \
            "${0##*/}" >&2
    exit 1
}

[ -d "$1" ] || {    ## validate 1st is valid directory
    printf "error: directory not found '%s'.\n" "$1" >&2
    exit 1
}

grep -q "^$2:" /etc/passwd || { ## validate 2nd is valid username
    printf "error: invalid user name '%s'.\n" "$2" >&2
    exit 1
}

epochsearch="$(date -d "$3" +%s)"
[ "$?" -eq 1 ] && { ## validate 3rd is valid date
    printf "error: invalid date format '%s'.\n" "$3" >&2
    exit 1 
}

[ "$epochsearch" -ge "$(date +%s)" ] && {   ## and date in the past
    printf "error: date given not in the past '%s'\n", "$3" >&2
    exit 1
}

## find files below dir for user modified before "date_given"
find "$1" -user "$2" ! -newermt "$3"

(note: since find will report invalid directory, user and time, the only validation that is necessary is that the date is in the past. It's up to you whether you want to validate the other inputs and handle the errors separately, for logging, etc..)

Substitute whichever version of the find command needed to accomplish your goal.

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85