Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Is there a way to rename files inside a folder as they're created?

I could run a cron job every few seconds to do something like...

find . -name "file.*" -exec sh -c 'echo mv "$1" "$(echo "$1" | sed s/file.*\$/"file-$(date).*"/)"' _ {} \;

but this seems really cumbersome, cycle-wise...

share|improve this question
    
FYI, cron can't go faster than once a minute. –  Kevin Aug 23 '12 at 2:09
add comment

2 Answers

up vote 5 down vote accepted

There's a framework in Linux called inotify which allows a program to register a handler to be called each time a file or a directory changes, so if you're writing a C program you can just use that. Obviously, your program will need to be running when the change occurs.

There is a special daemon called incron which is like "cron for inotify" and is able to run scripts when a file/directory changes. It can be installed with sudo apt-get install incron, then you'll need add a few lines to its configuration file.

Here's a helpful article: Linux incrond inotify: Monitor Directories For Changes And Take Action

If you search synaptic for "inotify" you'll find many more libraries and programs with similar functionality.

share|improve this answer
    
inotify has a more direct command line wrapper, but incron appears to be easier to use. –  Kevin Aug 23 '12 at 2:07
    
incron is pretty amazing, I will post my full solution once I get it working, thanks –  knishka Aug 23 '12 at 2:23
    
this is very odd, so I thought I had it working...I was able to create a simple test with my user account (not root), since the files I want to change are in my home dir. Anyways, so incrontab -e to open up the config, I set up ~/ IN_CREATE touch ~/test, so I navigated to ~/, and ran >foo, then test appeared, yay! So now I'm getting a little more complicated and trying a shell script, so now I have... ~/ IN_CREATE ~/test.sh, the contents of the shell script are: #!/bin/sh touch test, this is not working for whatever reason... –  knishka Aug 23 '12 at 3:38
    
Hmmm, so I started receiving bash: fork, cannot allocate memory errors, and looked at ps aux, it was full of my script trying to run and eating my memory up! Not sure what happened, but I have it under control now... –  knishka Aug 23 '12 at 4:57
add comment

So, using incron, I set it up by running sudo apt-get install incron.

My goal: Allow emails with picture attachments sent to an alias (sendtodropbox.com app) to be automatically copied into my blog's photo repository for posting.

Next I created a simple bash script:

#!/bin/bash
ls photo.JPG | while read a; do mv $a "$(echo "$a" | sed s/photo.JPG/"photo$(date +%a%b%d%H%M).jpg"/)"; done
mv photo* ~/Dropbox/Attachments /<photo repo>/

I place the script in ~/, then edit the /etc/incron.allow file to include my user name because these scripts and files are all in my home dir. Next I have to edit the incron config file by running incrontab -e.

In here I used ~/Dropbox/Attachments/ IN_MOVED_TO ~/script.sh (I used IN_MOVED_TO because the action of Dropbox placing a file in the Dropbox folder is considered a move)

This is working instantaneously when I email my Dropbox a picture from my phone now. I also tested incron with both root and my user name to make sure it worked, my first test as my user was: incrontab -e add the config: ~/ IN_CREATE touch ~/test, I then go to ~/, and run >foo, and test appears.

share|improve this answer
    
awesome, glad it worked –  Sergey Aug 23 '12 at 9:56
1  
I should note that, while it probably works in your specific case, the general rule is to never parse the output of ls. It can easily cause breakage when filenames include spaces or other "special" characters. Use shell globs instead. For example, for f in some_directory; do echo "now processing $f"; done It's simpler and more reliable. –  Scott Severance Aug 23 '12 at 23:24
    
Thanks for the tip @ScottSeverance! –  knishka Aug 24 '12 at 2:37
1  
Oops. for f in some_directory/*; do echo "Processing some_directory/$f..."; done I missed the all-important glob in my earlier comment, and it appears to be too late to edit it. –  Scott Severance Aug 24 '12 at 6:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.