Запустите приложение (GUI) на монтирование любых USB-устройств

Я выполняю гнома Ubuntu 16.04 4.4.0-62-универсальных LTS.

Я хотел бы сделать следующее: Выполненный также...

  • (a) приложение (GUI) [/path/to/my_app.desktop]
  • или (b) интерактивный сценарий в терминале [например: терминал гнома $-x/path/to/script.sh]

... каждый раз, когда монтирование любого (USB) устройство распознано.

Выполнение на X-сервере пользователя кажется обязательным, так как переменный ввод данных пользователем требуется в ответ на запущенное приложение / сценарий; это не может просто работать в фоновом режиме.

В течение прошлых 2 дней я провел обширное исследование и экспериментировал с обоими, udev-правилами и systemd.services. Моя повторяющаяся жесткая проблема, это, любой из последних подходов требует X-аутентификации. Altough, там уверенные, являются (замысловатыми) способами заставить аутентификацию произойти, мне не нравится идея нарушить врожденную безопасность системы путем экспорта переменных $XAUTHORITY от корня до сессии пользователя...

Я предполагаю, что должен быть альтернативный способ сделать следующий случай:

  1. обнаружьте, когда/если новое (USB) устройство было смонтировано
  2. запустите приложение (в терминале) с Полномочиями пользователя на пользовательском рабочем столе (т.е. Xsession пользователя?)
  3. (дополнительный: передайте devicename как переменную),

(создание монтирования - определенные .config файлы?; org.gnome.desktop.media-обработка?; сценарий автоматического запуска наблюдая/home/$USERNAME/media .mounts?; редактирование/etc/fstab;...?)

Любые подсказки высоко ценились бы.

3
задан 29 December 2017 в 11:46

1 ответ

(Старый ответ, новый ответ далее ниже)


Запустите скрипт или команду для выполнения каждый раз, когда карта памяти подключается

Если по любым причинам Вы не хотите использовать udev правила или что-либо более сложное, затем используйте сценарий ниже.

Просто запущение скрипта, с Вашей командой для выполнения как аргумент, сделает задание.

Сценарий:

#!/usr/bin/env python3
import subprocess
import time
import sys

cmd = " ".join(sys.argv[1:])

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

def identify(disk):
    command = "find /dev/disk -ls | grep /"+disk
    return "usb" in subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

mounted1 = get_mountedlist()
while True:
    time.sleep(4)
    mounted2 = get_mountedlist()
    if [d for d in mounted2 if all([not d in mounted1, d != "/", identify(d[0]) == True])]:
        subprocess.Popen(["/bin/bash", "-c", cmd])
    mounted1 = mounted2

Использовать

  1. Скопируйте сценарий в пустой файл, сохраните его как run_usbactions.py
  2. Тестовый прогон сценарий (например). команда:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

    В моем тесте я использовал, например:

    python3 /path/to/run_usbactions.py gedit file
    

    открываться file с gedit, после того как подключена карта памяти.

  3. Если все хорошо работает, добавьте его для Запущения Приложений: Тире> Приложения Запуска> Добавляет. Добавьте команду:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

Объяснение

  • Однажды в четыре секунды, в функции get_mountedlist(), сценарий читает вывод lsblk.

  • В случае, если дополнительные разделы или устройства смонтированы, вывод (например). команда:

    find /dev/disk -ls | grep sdc1
    

    будет включать строку usb, и идентифицируйте подсоединенный внешний диск как карту памяти.
    Смотря на него теперь, я очень хорошо мог заменить его большим количеством "pythonic" способа сделать его вместо системного вызова, но так как я скопировал его с более старого сценария, я (еще) не сделал.

  • впоследствии, если новый диск является usb, команда (+ возможный args), как начато " ".join(sys.argv[1:]) выполняется.




Править

(29 декабря 2017)

Используя pyudev

Так как я "встретил" pyudev, я думал, что должен совместно использовать основное упрощение и более четкую операцию, которую это приносит. Простой сценарий для выполнения любого действия со вставкой USB-устройства затем становится:

#!/usr/bin/env python3
import pyudev
import subprocess
import sys

cmd = " ".join(sys.argv[1:])

monitor = pyudev.Monitor.from_netlink(pyudev.Context())
monitor.filter_by('block')

for device in iter(monitor.poll, None):
    if all([
        device['ACTION'] == "add", 'ID_FS_TYPE' in device,
        device['ID_USB_DRIVER'] == "usb-storage",
        ]):
        print("added", device.get('ID_FS_LABEL'))
        subprocess.Popen(["/bin/bash", "-c", cmd])

Использование

Удостовериться pyudev установлен:

sudo apt install python3-pyudev

Дальнейшие инструкции точно подобны.

3
ответ дан 1 December 2019 в 16:20

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

Похожие вопросы: