1830207 Members
1788 Online
109999 Solutions
New Discussion

Query

 
SOLVED
Go to solution
Allanm
Super Advisor

Query


I need to trigger some action if any two of conditions are met on my system :

I want to have a cron job running ,which on a filesystem :

1) checks whether a file is modified then it triggers an action

2) if a new file is created then again some action is triggered .

Question is how to accomplish the above two tasks through shell scripting ( no perl please since I dont know much abt it ).
13 REPLIES 13
James R. Ferguson
Acclaimed Contributor

Re: Query

Hi:

> checks whether a file is modified then it triggers an action

Look at the manpages for 'touch' and 'sh-posix'.

You can create a reference point (file) with 'touch -r' that captures your file's last modification timestamp. Then compare what you last saw with the current value using something like 'myfile -nt reffile'. If the you file has been updated, "do-your-thing".

> if a new file is created then again some action is triggered.

This is really a corollary of the first case. This is *NO* such thing as a "creation" timestamp in Unix. The "birthdate" of a file is coincidently the same as its modification timestamp when a file is first instantiated.

Regards!

...JRF...

A. Clay Stephenson
Acclaimed Contributor

Re: Query

You need to better define your question. Do you want to know if specific files are modified/created or do you want to know if any files in an entire filesystem are modified/created?

If you can limit it to specific files then that is reasonable. If you want to do it on an entire filesystem then that is going to be a huge resource hog. You should also be aware that there is no way to know when a file was created. UNIX does not store that data. In order to detect new files, you would have to keep a database of existing files and compare that to currently found files.

Do a google search on "tripwire"; that may be just what you are looking for.
If it ain't broke, I can fix that.
Allanm
Super Advisor

Re: Query


Here is what I wanted ..I figured out through the find command :

find . -type f -mtime -1 |grep CVS |grep -v Codemagr

this gives me the following output :

./psystem/scrr/pms/scripts/CVS/s.install

..now I want to strip down the the output in which I can cd to psystem/scrr/pms/scripts only. How to get this output ? Please note that the depth can vary... ( basically I want to cut the last 2 fields - starting with /CVS/s.install)

Allanm
Super Advisor

Re: Query

JRF /Clay .. can you help please....

thanks.
A. Clay Stephenson
Acclaimed Contributor

Re: Query

There are many ways to do this (here's one using your existing find output to feed awk):

find . -type f ..... | awk -F '/' '{if (NF > 1) {printf("%s/%s\n",$(NF - 1),$NF) } else print $0}'

You could also use cut specifying a field separator. You really should get away from using grep, especially without anchored expressions, because you are going to get things you don't exit.

For example, grep tom will get tom,tommy,atom,atomic,anatomy when all you wanted was "tom".
If it ain't broke, I can fix that.
Allanm
Super Advisor

Re: Query

Thanks for the reply Clay , but its giving me a syntax error .
Allanm
Super Advisor

Re: Query

I removed the space between -F and '/' and it removed the syntax error but the output I am getting now is not what i originally wanted :


%s/%s
CVS s

I wanted :

psystem/scrr/pms/scripts

OR

psystem/scrr/pms/scripts/
Dennis Handly
Acclaimed Contributor

Re: Query

If you know you want under psystem/scrr/pms/scripts, you should start your find there.

>grep CVS |grep -v Codemagr

You can code these in the find itself:
find . -type f -mtime -1 -path "*/CVS/*" ! -path "*/Codemagr/*"

>but the output I am getting now is not what i originally wanted:

Did you want the last two directory components? Or to remove them?

You might want to use a nested dirname(2):
find . | xargs -n1 dirname | xargs -n1 dirname | sort -u


Allanm
Super Advisor

Re: Query

Finally its very near but yet so far :

find . -type f -mtime -1 |grep CVS |grep -v Codemagr|awk -F"./" '{print $2}'|awk -F"CVS" '{print $1}'

and getting :

/psystem/scrr/pms/scripts/

and I want :

psystem/scrr/pms/scripts/

A. Clay Stephenson
Acclaimed Contributor

Re: Query

find . -type f | awk -F '/' '{if (NF > 1) {printf("%s/%s\n",$(NF - 1),$NF) } else print $0}'

I don't see any syntax errors but this is all one line and must be entered as such/ Moreover, where I have single quotes they should be used and where I have double quotes they should be used. This will print the last directory and filename regardless of depth.
If it ain't broke, I can fix that.
A. Clay Stephenson
Acclaimed Contributor

Re: Query

find . -type f | awk -F '/' '{if (NF > 1) {printf("%s/%s\n",$(NF - 1),$NF) } else print $0}'

I'll try again using the retain format option.
If it ain't broke, I can fix that.
Dennis Handly
Acclaimed Contributor
Solution

Re: Query

>and getting: /psystem/scrr/pms/scripts/
>and I want : psystem/scrr/pms/scripts/

If you want to remove the first "/", you can use sed:
... | sed 's:^/::'

Or awk's substr function: substr($0, 2)

Allanm
Super Advisor

Re: Query

Thanks Clay / Dennis.