Skip files in use

Hi all,
i'm trying to configure a script that will find and gzip the searched files,
this is easy enough,

find /var/log/myfolder/*.log -type f -mtime +1 -exec gzip {} \;
cd /var/log/myfolder/
mv *gz myzipped_folder/

but what it would be very handy is to skip the files in use,because tomcat its going to check for some file that my script have gziped and move and alerting me by email for not enough space on HDD,when in reality there is enough,
you may suggests why don't you simply restart Tomcat,well i cant do that,to many jobs running 24h to 24h,so is any way to implement on my script the option skip files in use by Tomcat?

Thanks in advance
Charli.

If you can't get a short downtime to wrap that file, reducing the log level or adding more space to the filesystem might be an option.
Also logrotate is said to be able to truncate open log files. Never tried that but maybe worth trying it.

Thanks for the reply,
yes i already have

logrotate

for some log files,i wanted to implement this script now,till i configure all of the log files with logrotate,because the log files are really tons of them,so with a script it wil solve the issue temporarily,and give me the needed time to configure out logrotate.
Any suggestions?

You could build the list of files you want you get with find , but instead of executing the gzip, redirect the output to a temporary file, have a second list which works as your exclude, use something like a

grep -vf exludelist.txt outputofthefindcommand.txt

and decide by this to compress them or not.

i cant use an exclude list as the files in use aren't always the same,
they always change.

Listing files opened by a process is difficult as this can be very transient info, but

lsof -c tomcat

should list those files tomcat actually acts upon.

any suggestion on how to implement this on my script,and to skip the printed files?

Parse the output, maybe with awk and build your exclude list with this.
But as RudiC already mentioned, the information can be very short-lived and also a file can be in use right after you gathered your list.

In bash, you could use (excerpt from man bash):

... extended pattern matching operators ...
pattern-list is a list of one or more patterns separated by a |.
...
!(pattern-list)
                     Matches anything except one of the given patterns

So - create a "|" separated lsof pattern list in a variable and use the !($var) operator to exclude those files from processing.

well till here its ok,

#!/bin/sh

lsof -p `ps -elf | grep tomcat | grep -v grep | grep -v monitor | awk {'print $4'}` | grep "/var/log" | awk {'print $9'} > "/tmp/mylogs.txt"

but i need to find everything that is not on that file on a specific folder

find find /var/log/myfolder/ --exclude from /tmp/mylogs.txt -type f -mtime +1 -exec gzip {} \;
Any one could make an example of the script, please?

No need for that long contruct; given you are using bash, try this to ls all files in /var/log NOT open by the command "sleep":

ls -d /var/log/!($(lsof -Fn -c sleep  2>/dev/null|awk -F"[/]" '/\/var\/log/{printf "%s|",$4}'))

What it does: lsof outputs the open files for command sleep, including path, which is removed by awk, adding the "|" separator. This then goes into the bash extglob operator !(...) to be used by ls.

it is not a bash,
so the error is

event not found

.

If the error is what you post (I had the same during testing), there is a chance it will understand a slight modification of above. Assign the $(lsof ...) stuff to a variable and try /var/log/!($var). Follow up with option -x set.

Thanks for trying to help,i'm working on it,

not solved yet.

will update later...