3

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...

1
  • FYI, cron can't go faster than once a minute.
    – Kevin
    Aug 23, 2012 at 2:09

2 Answers 2

5

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.

4
  • inotify has a more direct command line wrapper, but incron appears to be easier to use.
    – Kevin
    Aug 23, 2012 at 2:07
  • incron is pretty amazing, I will post my full solution once I get it working, thanks
    – knishka
    Aug 23, 2012 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, 2012 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, 2012 at 4:57
1

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.

2
  • 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. Aug 23, 2012 at 23:24
  • 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. Aug 24, 2012 at 6:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .