1

Within a given directory in linux environment, I need to pick all files modified after a certain date (let's say 7 days) as well as all directories (only in root directory, hence non recursively) created after the same date.

After that, I have to take care of 3 directories which except the last given rule. For these, the process has to be recursive within each of them. In one of these directories, there's a file to be excluded no matter what.

Finally, I have to add all the objects matching these patterns to a single .tar archive. Every file/directory must of course keep full relative path within the .tar file (starting from base directory).

So let's assume we have:

myHome
|-- normalDir1                  //  older than 7 days
|   |-- blah.txt
|   |-- to_be_excluded_nmw.txt  //  should never be included anyways
|   `-- poems.txt
|-- normalDir2                  //  created yesterday
|   |-- blah2.txt               /*
|   |-- whatever2.txt            *  Since it's a normal directory,
|   |-- whatever3.txt            *  I want to exclude these files from .tar
|   `-- poems2.txt               */  
|-- exceptionDirectory1         //  older than 7 days
|   |-- actions                 //  older than 7 days
|   |   `-- power.sh            //  older than 7 days
|   `-- events                  //  older than 7 days
|       |-- deploy.php          //  older than 7 days
|       `-- set.php             //  older than 7 days
|-- exceptionDirectory2         //  older than 7 days
|   |-- actions2
|   |   `-- power2.sh           //  created yesterday
|   `-- events2                 //  older than 7 days
|       |-- deploy2.php         //  created yesterday
|       `-- set2.php            //  older than 7 days
|-- file_to_be_updated.php      //  created yesterday
`-- file_NOT_to_be_updated.php  //  older than 7 days

the resulting .tar should contain:

./normalDir2/
./exceptionDirectory2/actions2/power2.sh
./exceptionDirectory2/events2/deploy2.php
./file_to_be_updated.php

I've created this script:

#!/bin/bash
TODAY=`date --rfc-3339=date`
FILENAME=$TODAY-package.tar
find ./require ! -name db_connection.php         ! -path ./require -mtime -7 -print | xargs tar cvf `date --rfc-3339=date`-package.tar
find ./img                                       ! -path ./img     -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar
find ./plugin                                    ! -path ./plugin  -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar
find . -maxdepth 1 ! -name $TODAY-package.tar.gz ! -path .         -mtime -7 -print | xargs tar uvf `date --rfc-3339=date`-package.tar

but it doesn't seem to work properly as it quits almost immediately with this error:

tar: ./img: Impossibile open: Is a directory

Notice "require", "img" and "plugin" being the three special directories to be treated recursively. What's wrong with the script? Thank you for your assistance.

  • 1
    Did you try to use directly tar --after-date ? – Hastur May 14 '14 at 11:45
  • Actually I didn't, maybe my approach is a little winding. But I'd still have to take care about the exceptions as stated above, and I fear simply following your tip wouldn't solve the whole thing. – Seether May 14 '14 at 11:59
1

What is causing the error is that you have spaces or other special characters in the filenames under ./img.

Instead of using the -print option to find, use -print0 and the corresponding -0 option to `xargs':

 find ./img ! -path ./img -mtime -7 -print0 | xargs -0 tar uvf `date --rfc-3339=date`-package.tar
  • I've tried this solution first as it was the most similiar to mine, but doesn't seem to fix the issue. – Seether May 14 '14 at 13:25
0
  • Rather than find ./foo ! -path ./foo you can use find -mindepth 1 ./foo. This ensures that only files inside the specified paths are printed.
  • If you have GNU tar you can use --exclude=PATTERN. That way you should be able to write something like this:

    today="$(date --rfc-3339="date")"
    last_week="$(date --rfc-3339="date" --date="-7 days")"
    tar --no-recursion --exclude=db_connection.php --after-date="$last_week" cvf "${today}-package.tar" .
    tar --after-date="$last_week" uvf "${today}-package.tar" ./require ./img ./plugin
    
  • That's nice and I've modified my script already, but the error remains. (EDIT: was referring only to first point when writing) – Seether May 14 '14 at 12:04
  • Running the copy-pasted version of this script results in a error, perhaps the "cvf" and "uvf" params are misplaced. I tried moving them on first position without much success, the best I managed to achieve is obtaining a couple of tars named "--no-recursion" and "--after-date", obviously with no files/directories exclusion rules applied. – Seether May 14 '14 at 13:35
0

I write it on the fly, try if it functions something around

tar cvf   --no-recursion --after-date $yourdate $TarFile * */* 
tar uvrf  --after-date $yourdate $TarFile ./require ./plugin ./img

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.