Скрипт не работает при вызове правилом udev

Я пользователь Linux Mint, и я пытаюсь написать правило, которое выполняет скрипт, когда я подключаю USB. #!/bin/sh script не удается получить доступ к USB (даже с обычным компакт-диском), а если я запускаю тот же скрипт из командной строки, он работает отлично.

Правило, которое я создал для этой цели:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="058f", ATTR{idProduct}=="6387", RUN+=="/home/dario/bin/backup_usb"

где backup_usb, например, выглядит так:

#!/bin/sh
sleep 10
cd /media/dario/ 
echo " I am now in: $(pwd)" >> /home/dario/bin/log.log
cd /media/dario/DARIO_USB/  # That's the device just plugged in.
echo " I am now in: $(pwd)" >> /home/dario/bin/log.log

Результат:

I am now in: /media/dario/ 
and now in: /

пока я ждал:

I am now in: /media/dario/ 
and now in: /media/dario/DARIO_USB/

Буду очень благодарен за любую помощь.

(Это отредактированная версия моего вопроса)


person dario    schedule 27.01.2016    source источник
comment
Не работает недостаточно для нас, чтобы работать. Как минимум настроить логирование. Кроме того, все элементы =3D не работают — каждый =3D должен быть одним знаком =, а =20 аналогичным образом является escape-кодом для пробела.   -  person Charles Duffy    schedule 27.01.2016
comment
Кроме того, вы помечаете свой вопрос bash, но используете #!/bin/sh для POSIX sh. Это может быть только одно или другое; что он?   -  person Charles Duffy    schedule 27.01.2016
comment
Кажется, я не знаю, как это называется. Я использую #!/bin/sh. Является ли tag: shell правильным тегом?   -  person dario    schedule 28.01.2016
comment
Я не разбираюсь в сценариях, так что, пожалуйста, просветите меня!   -  person dario    schedule 28.01.2016
comment
Да, shell или sh больше подходят, чем bash для #!/bin/sh. Или вы можете просто использовать #!/bin/bash и сохранить тег bash. :)   -  person Charles Duffy    schedule 28.01.2016
comment
Кстати, предположение, что ваше правило udev, срабатывающее когда устройство подключено, происходит не только после его подключения, но и после его монтирования, не является допустимым предположением. Само монтирование ведь срабатывает udev.   -  person Charles Duffy    schedule 28.01.2016
comment
Кроме того, вы хотите либо =, либо +=, а не +==, для RUN.   -  person Charles Duffy    schedule 28.01.2016


Ответы (1)


Во-первых, ваше правило неверно. Рассмотрим что-то вроде:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="058f",
ATTR{idProduct}=="6387", RUN+="/home/dario/bin/backup_usb"

Второй: Убейте sleep 10. Если udev запускает сценарии по порядку и ждет завершения каждого, прежде чем запускать следующий, он потенциально может заблокировать любой последующий сценарий (например, тот, который выполняет монтирование), предотвращая его выполнение вообще. Мы собираемся сделать это по-другому, поместив опрос в фоновом режиме:

#!/bin/bash
#      ^^^^ - has to be bash, as the C-style for loop syntax used below is a bashism
#             ...as is the [[ ]] construct.

exec </dev/null >/home/dario/usb.log 2>&1
set -x
cd /media/dario || exit
(
  for ((retries=0; retries<10; retries++)); do
    [[ -d DARIO_USB ]] && grep -q -e DARIO_USB /proc/mounts && continue
    sleep 1 # retry
  done
  cd DARIO_USB || exit
  echo "SUCCESS"
) &
person Charles Duffy    schedule 27.01.2016
comment
Спасибо за Ваш ответ. Я редактирую свой вопрос. У меня возник вопрос: что делает exec 2›/path/to/logfile; установить -х; делать? Кроме того, операции, которые я прошу, тривиальны и отлично работают при вызове того же скрипта из терминала. - person dario; 28.01.2016
comment
exec 2>/path/to/logfile перенаправляет stderr из вашего скрипта в файл с именем /path/to/logfile. set -x регистрирует каждую команду, выполняемую сценарием. - person Charles Duffy; 28.01.2016
comment
Когда вы запускаете из терминала, ваша среда будет существенно отличаться. Возможно, вы зависите от PATH элементов, которые присутствуют в вашей интерактивной оболочке, но не в оболочке, вызванной udev — какой бы ни была причина, журнал должен прояснить ее. - person Charles Duffy; 28.01.2016
comment
Я рад, что ваш код сработал. Спасибо за помощь. Я принял этот ответ, потому что он был наиболее значимым, но моей главной целью было понять свою ошибку, и, к сожалению, я до сих пор этого не сделал. В любом случае спасибо за вашу помощь. - person dario; 01.02.2016
comment
@dario, поскольку этот код (ну, части в ( ... ) &) работает в фоновом режиме, другие сценарии udev не блокируются в ожидании его. Это означает, что отдельный триггер, который фактически монтирует USB-устройство, не застревает за вашим сценарием, который требует монтирования устройства, прежде чем оно заработает. Это помогает? - person Charles Duffy; 01.02.2016
comment
@dario, ... я не уверен, что это единственное, что здесь происходит, но мне нужен журнал stderr, испускаемый другим вашим скриптом, работающим с set -x, чтобы поставить определенный диагноз (считай, как первый строка после шебанга, exec 2>/tmp/mount.log; PS4=':$LINENO+'; set -x). Без этого содержания вопроса краткое и определенное объяснение невозможно. - person Charles Duffy; 01.02.2016
comment
Большое спасибо. На данный момент я доволен. :) У меня много вопросов, так как я не привык к скриптам bash, но я думаю, что это не то место! Желаю тебе всего наилучшего. - person dario; 02.02.2016
comment
Знаете ли вы, как сделать то же самое с OS X? Это не должно сильно отличаться, этот метод, который вы мне предложили, отлично работает для Linux! - person dario; 14.02.2016