Выполнение скрипта при вставке флешки

Как я могу написать сценарий, который запускает событие?

Когда я вставляю флешку, Ubuntu монтирует ее и автоматически открывает Nautilus. Когда это происходит с определенной флешкой, я бы хотел открыть вторую вкладку с определенной папкой.

Я не думаю, что это можно сделать с помощью скрипта Nautilus, но как я могу сделать это с помощью скрипта Linux или расширения Nautilus?

1 ответ

Решение

Если вы запустите скрипт ниже в фоновом режиме, он проверит наличие подключенных томов. Если подключен один из определенных вами дисков, он автоматически откроет заданную папку в nautilus.

Небольшая проблема заключалась в том, что nautilus не поддерживает открытие каталога на новой вкладке из командной строки, только в новом окне. Это означает, что начальное окно, которое появляется, если вы вставляете USB-диск, должно быть изящно закрыто. Скрипт использует wmctrl чтобы сделать это, в тот момент, когда выбранная вами папка откроется.

Возможно, вам придется сначала установить его:

sudo apt-get install wmctrl

Сценарий

#!/usr/bin/env python3

import subprocess
import time

#--
drivename_folders = [("My Passport", "docs"), ("7827-2F8C", "sanel")]
#--

def get_mountedlist():
    return [item[item.find("/"):] for item in subprocess.check_output(
            ["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]

done = []

while True:
    mounted = get_mountedlist()
    new_paths = [dev for dev in mounted if not dev in done]
    valid = sum([[(drive, drive+"/"+item[1], item[0]) for drive in new_paths \
                  if item[0] in drive] for item in drivename_folders], [])

    for item in valid:
        open_window = "nautilus  "+"'"+item[1]+"'"
        close_window = "wmctrl -c  "+"'"+item[2]+"'"
        subprocess.Popen(["/bin/bash", "-c", open_window])
        time.sleep(1)
        subprocess.Popen(["/bin/bash", "-c", close_window])

    done = mounted
    time.sleep(2)

Как пользоваться

  1. Скопируйте скрипт в пустой файл

  2. Установите ваши диски и папки

    В разделе заголовка скрипта измените строку:

    drivename_folders = [("My Passport", "docs"), ("7827-2F8C", "MyFolder")]
    

    где каждый кортеж представляет диск (имя) и папку внутри диска, которая должна быть открыта. Я оставил свои "тестовые" имена в качестве примера.
    Если вы не уверены в точном названии вашего диска, запустите lsblk чтобы увидеть имя (без предшествующего пути к точке монтирования)

  3. Сохранить скрипт

    Сохранить скрипт как open_folder.py и запустите его командой:

    python3 /path/to/open_folder.py
    

Если все работает, как вы ожидали, добавьте его в свои приложения автозагрузки

Как это устроено

  • Каждые две секунды скрипт запускает lsblk Команда для проверки всех подключенных томов.
  • Если он находит одно или несколько вновь смонтированных имен томов, он проверяет, находится ли это имя в списке томов, которые вы хотите открыть определенным образом (открытие подкаталога).
  • Сценарий открывает подкаталог тома, который вы определили, и закрывает окно (корневое) диска, которое было автоматически открыто при подключении диска.
  • Чтобы предотвратить повторное открытие папок, том добавляется в список "Готово", пока том не будет отключен.

Другие файловые менеджеры

Я проверил это на pcmanfm (Lubuntu) и thunar (Xubuntu) и, как и ожидалось, в обоих случаях работает нормально.

Если вы хотите использовать его на Lubuntu или Xubuntu, измените строку:

open_window = "nautilus  "+"'"+item[1]+"'"

чтобы:

open_window = "thunar "+"'"+item[1]+"'"
(for Xubuntu)

или же

open_window = "pcmanfm "+"'"+item[1]+"'"
(for Lubuntu, also disable in pcmanfm's preferences: Media > "Show available options for removable media")

Конечно, убедитесь wmctrl установлено

Скорее всего, это будет работать и на других файловых менеджерах.


Обобщенная версия скрипта

Версия скрипта выше специально для одной ситуации. Чтобы иметь возможность использовать сценарий в более широком диапазоне целей (для запуска любой команды при подключении определенного диска, например, для ее резервного копирования), может быть полезна приведенная ниже версия.

В этом случае в разделе заголовка скрипта кортежи представляют:

 drivename_folders = [(<drivename_a>, <command_a>), (<drivename_b>, <command_b>)]

см. настройку "тест" в скрипте ниже.

Сценарий

#!/usr/bin/env python3

import subprocess
import time

#--
drivename_command = [("My Passport", "gnome-terminal"), ("F806-0C50", "gedit")]
#--

def get_mountedlist():
    return [item[item.find("/"):] for item in subprocess.check_output(
            ["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]

done = []

while True:
    mounted = get_mountedlist()
    newly_mounted = [dev for dev in mounted if not dev in done]
    valid = sum([[(drive, item[1]) for drive in newly_mounted \
                  if item[0] in drive] for item in drivename_command], [])
    for item in valid:
        subprocess.Popen(["/bin/bash", "-c", item[1]])
    done = mounted
    time.sleep(2)

Как пользоваться

  1. Скопируйте скрипт в пустой файл

  2. Установите ваши диски и команды

  3. Сохранить скрипт

    Сохранить скрипт как drive_run.py и запустите его командой:

    python3 /path/to/drive_run.py
    

Если все работает, как вы ожидали, добавьте его в свои приложения автозагрузки

Другие вопросы по тегам