PCgeekdom.com - PC Tricks and Projects

Sunday, October 07, 2007

Bash: Automatically make/update a symbolic link to the newest file in a directory


I needed a script that could monitor a directory for file changes, and upon any changes create or update a symbolic link to the newest file in the directory. For this particular application, I was interested only in mpg files, and wanted the script to only monitor and link to mpg files.
This is what I came up with:

echo $$ > /home/vlc/video/watch_dir.pid
touch /tmp/watch_dirb.$$
while true
ls /home/vlc/video/FolderName -l --hide='newestfile.mpg'| \
grep mpg > /tmp/watch_dira.$$

diff /tmp/watch_dira.$$ /tmp/watch_dirb.$$ || \
ln -sf `ls /home/vlc/video/FolderName -lt \
--hide='newestfile.mpg' | grep mpg | head -n 1 | awk '{print $8}'` \

cp /tmp/watch_dira.$$ /tmp/Watch_dirb.$$
sleep 60

There is probably a better method, but this seems to work well.
Script Explanation:
The first line writes the scripts process id to file to make it easier to terminate the script e.g. kill `cat watch_dir.pid`
The directory monitoring is done by writing the folder contents (using ls) to a tmp file, and then comparing the contents of the current file, filea, with the file populated from the last check, fileb.
If diff does detect a change then this command is executed:
ln -sf `ls /home/vlc/video/FolderName -lt --hide='newestfile.mpg' | grep mpg | head -n 1 | awk '{print $8}'` /home/vlc/video/FolderName/newestfile.mpg
This line creates a symbolic link named newestfile.mpg pointed to the newest file in that directory. The newest file is determined by ls -lt, it hides newestfile.mpg so as not to create a link to the link. It then uses grep to find just the mpg files and takes the top entry with head -n 1, it only needs the filename so only the 8th field is used. (Note: depending on your distro the filename may not be in the 8th field and the awk command may need adjusting. In my own testing, I have found that the filename is the 8th field in Ubuntu, but the 9th field in Fedora.
The script then waits for 1 minute and checks again.


  • The post isn't newest is it, but now and then using `ls -1t | head -n 1` prevents piping through awk and thus any distro-related trouble.

    By Anonymous Anonymous, at 4:43 PM  

  • Nice trick.

    By Anonymous Computricks, at 4:57 AM  

Post a Comment

<< Home