Solved

BASH Scripting Check If a file is being Accessed

Posted on 2010-11-15
17
735 Views
Last Modified: 2012-05-10
I need to use a find script to find files of a certain type then I would like to check if they are being accessed and if they are clear the contents otherwise remove the file. I'm ok with the find part but should I pipe the output to some kind of If statement.
0
Comment
Question by:Lico_w
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
  • 4
17 Comments
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34135597
I  assume that this Q is releated to the other one requesting assistance on how to clear a file?

If so, and if you have the lsof utility at hand, you could do:

find ./ -name "*.log" -type f -mtime +1 | while read file ; do lsof $file >/dev/null || >$file; done

lsof returns a "false" returnconde if the file is not open, so we use "||" here.
 
wmp
0
 

Author Comment

by:Lico_w
ID: 34135738
Ok I think I understand this, we are doing the find, piping it to the while loop, then we're checking if the file is open (lsof $file) then we are copying the contents of a null file to the current file (>/dev/null || >$file).

Please confirm and then I will award points.
0
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34135782
That's quite correct , but "copying the contents of a null file ..." doesn't describe exactly what happens.

>$file just opens a file for output and closes it immediately afterwards, because there is no data to be written to it (as opposed to e.g. echo "This File is Empty!" >$file), thus effectively emptying it.

wmp
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Lico_w
ID: 34135959
Just tested this and it doesn't work. I have logged on with another user and left the file open with vi. I've then logged on as myself and ran the script but it didn't clear the file?
0
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34136597
vi does not keep the file open.

It is read into memory, that's all.
0
 
LVL 2

Expert Comment

by:ckiral
ID: 34138044
Hi,

I assume that you want to clear contents of  open files only and then remove if found files are already closed.  

I suggest to write a  little script to make necessary tests on find command's output.
Try this one:
---
#!/bin/bash
#FileCleaner.sh
lsof $1 && > $1 && exit 0;
rm $1
exit 0
---
You can now use this script with your find command as follows:

find ./ -name "*.log" -type f -exec ./FileCleaner.sh '{}' \;

-
As woolmilkporc already mentioned; you can not test it with vi.
In one terminal you can type
cat  > testfile
(It will open a new file handler)
Then type some text in to it. In an  other terminal you should now see your text using command
cat testfile
After that try the find command  with testfile pattern
When command exit; you'll notice that the file is now empty as you requested...

--

0
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34139917
Attention!

lsof returns "1" if the file is not open!

So you should use || instead of &&!

wmp
0
 
LVL 2

Assisted Solution

by:ckiral
ckiral earned 100 total points
ID: 34140117
i agree;
in the script we clear the content of  the file if it's open..
I don't see any errors here??
---
if file is open then clear the contents and exit...
----
lsof $1 && > $1 && exit 0;
---
So && usage is correct; am i missing something?

0
 
LVL 68

Accepted Solution

by:
woolmilkporc earned 400 total points
ID: 34140136
Or is it really so that you want to clear open files only?

In this case && is of course correct!

In my version:

find ./ -name "*.log" -type f -mtime +1 | while read file ; do lsof $file >/dev/null && >$file || rm $file; done
0
 
LVL 2

Expert Comment

by:ckiral
ID: 34144804
woolmilkporc; in my opininon your version will never evaluate closed file case...
The command will exit as soon as lsof will return false.

Please confirm...
0
 
LVL 2

Expert Comment

by:ckiral
ID: 34155628
Please forget my last post about woolmilkporc's version, it will work as expected.
My mistake...
0
 

Author Comment

by:Lico_w
ID: 34195195
Apologies I've been away for a week, I'm going to test this now and award points for my outstanding questions. Is there a way I can keep a file open so that I can test this? Obviously as you stated you can't use vi but is there another option?
0
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34195233
You could open a file (and empty it if it exists) with

cat > filename

or open an existing file without emptying it (but please be careful - do not destroy a file you need) with

cat >> filename

Terminate "cat" with <Ctrl><C>

wmp
0
 

Author Closing Comment

by:Lico_w
ID: 34195355
Many thanks for the comments, does exactly what I need it to do and I've also learned a lot!!
0
 

Author Comment

by:Lico_w
ID: 34195577
One final thing...if I wanted to rm the file i.e. if it ISN'T being accessed how would I do that? Is it just a simple modification on the above or should I post a new question?
0
 
LVL 68

Expert Comment

by:woolmilkporc
ID: 34195619
That's what this thing is supposed to do:

find ./ -name "*.log" -type f -mtime +1 | while read file ; do lsof $file >/dev/null && >$file || rm $file; done

The && >$file part means "Empty it if it's being accessed" and the || rm $file part means: remove it if it's not being accessed.

To just remove files not being accessed without the "emptying" part modify like below:

find ./ -name "*.log" -type f -mtime +1 | while read file ; do lsof $file >/dev/null || rm $file; done

wmp



0
 

Author Comment

by:Lico_w
ID: 34195900
I thought that was the case but seems I had a slight typo preventing the rm bit working, thanks again
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hello fellow BSD lovers, I've created a patch process for patching openjdk6 for BSD (FreeBSD specifically), although I tried to keep all BSD versions in mind when creating my patch. Welcome to OpenJDK6 on BSD First let me start with a little …
Using libpcap/Jpcap to capture and send packets on Solaris version (10/11) Library used: 1.      Libpcap (http://www.tcpdump.org) Version 1.2 2.      Jpcap(http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/index.html) Version 0.6 Prerequisite: 1.      GCC …
Learn how to get help with Linux/Unix bash shell commands. Use help to read help documents for built in bash shell commands.: Use man to interface with the online reference manuals for shell commands.: Use man to search man pages for unknown command…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question