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
do
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}'` \
/home/vlc/video/FolderName/newestfile.mpg
cp /tmp/watch_dira.$$ /tmp/Watch_dirb.$$
sleep 60
done
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.
This is what I came up with:
echo $$ > /home/vlc/video/watch_dir.pid
touch /tmp/watch_dirb.$$
while true
do
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}'` \
/home/vlc/video/FolderName/newestfile.mpg
cp /tmp/watch_dira.$$ /tmp/Watch_dirb.$$
sleep 60
done
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.