Ubuntu – Autostart program whenever a file is added to a folder

automationbashfirefox

I have Lubuntu 14.04 LTS on my laptop for a few weeks now. I have been working on customizing the OS and such quite a bit, as well as installing everything that I need for daily usage. One thing I did is write a C program that, when run, offers to quickly copy or move any file to any location from the Downloads folder. New destinations can be easily added.

Anyway, I did this because I disperse my files all over the place from my Downloads folder, so changing the default download location in Firefox really isn't the answer. Instead, I want to be able to choose on a case by case basis. The program works fine, however, I want to set it run to automatically in a terminal anytime a file is downloaded to the Downloads folder.

Best Answer

There are a few solutions:

Option 1: without installing additional software:

You can use a minor script to keep an eye on the Downloads folder, like the watch command does, but make sure it only executes a command when a file is added to the directory. Copy the script below into an empty file, set the path to the folder to watch, and the command to run if a file is added to the directory. Save it as watch.py and make it executable for convenience reasons (so you won't have to use the language prefix). Add it to your startup applications:

- in Lubuntu:

Preferences > Default applications for LXSession, then choose "Autostart"

- or in Ubuntu:

System Settings > Keyboard > Shortcuts > Custom Shortcuts

The add the command to start the script on login:

/path/to/watch.py

The script:

#!/usr/bin/env python

import subprocess
import time

folder = "/path/to/folder/to/watch"
command_to_run = "command_to_run"

def get_drlist():
    return subprocess.check_output(["ls", folder]).decode('utf-8').strip().split("\n")

while True:
    drlist1 = get_drlist()
    time.sleep(2)
    drlist2 = get_drlist()
    if len(drlist2) > len(drlist1):
        subprocess.Popen(["/bin/bash", "-c", command_to_run])

Option 2: using inotify-tools:

inotify-tools is a tool you can use (a.o.) to watch a defined folder and take (defined) actions if a new file is added to the folder.

  1. Install inotify-tools

    sudo apt-get install inotify-tools
    
  2. Paste the script below in an empty file, set the folder to watch ("/path/to/your/downloadfolder"), define the command it should run ("command-to-run-your-application") safe it as notifyscript.sh, make it executable for convenience reasons, and add it to your startup applications: (Preferences > Default applications for LXSession, then choose "Autostart". Add the command:

    /path/to/notifyscript.sh
    

The script:

#!/bin/bash

while true
do
    fileName=$(inotifywait -r -e create /path/to/your/downloadfolder | sed -r 's/^.*CREATE(,ISDIR)*\s+(.*)$/\2/g')
    command-to-run-your-application
done

Note that in both cases your application will be called at the moment the file is created, but not yet fully downloaded. If the download is large, it can take some time.


EDIT

Additionally, if the newly added file has to be used as an argument for the command you run when the file is added, use the version below:

It uses the format:

<application> <file>

so the "usual". As an example, I left gedit, so the script will (try to) open the newly added file with gedit.

#!/usr/bin/env python

import subprocess
import time

folder = "/path/to/folder/to/watch"
application = "gedit"

def get_drlist():
    return subprocess.check_output(["ls", folder]).decode('utf-8').strip().split("\n")

while True:
    drlist1 = get_drlist()
    time.sleep(2)
    drlist2 = get_drlist()
    for file in [f for f in drlist2 if not f in drlist1]:
            command = application+" '"+folder+"/"+file+"'"
            subprocess.Popen(["/bin/bash", "-c", command])