Выполнение скрипта после монтирования USB-ключа - PullRequest
0 голосов
/ 09 февраля 2019

Я пытаюсь запустить скрипт для идентификации USB-ключа, проверив его метку, а также наличие файла с идентификатором.Я был впервые вдохновлен этим -> Скрипт не работает, когда вызывается правилом udev

Сначала это правило udev.Он работает правильно и правильно вызывает мой скрипт.

KERNEL=="sd[b-z]1", SUBSYSTEM=="block", ACTION=="add", GROUP="plugdev", OWNER="tuxin", RUN+="/home/tuxin/insert-usbkey.sh %k"

Вот скрипт, приведенный к самому простому выражению для проверки операции.

#!/bin/bash
exec </dev/null >/tmp/key-inserted.log 2>&1; PS4=':$LINENO+'; set -x

KEY_LABEL="DEV_JP"

cd /media/tuxin || exit
(
  for ((retries=0; retries<10; retries++)); do
    [[ -d "$KEY_LABEL" ]] && grep -q -e "$KEY_LABEL" /proc/mounts && continue
    sleep 1
  done
  cd "$KEY_LABEL" || exit
  echo "SUCCESS"
) &

К сожалению, несмотря на монтируемый ключ, «УСПЕХ» никогда не записывается в файл журнала, его содержимое:

:4+KEY_LABEL=DEV_JP
:6+cd /media/tuxin
:8+(( retries=0 ))
:8+(( retries<10 ))
:9+[[ -d DEV_JP ]]
:10+sleep 1

Мы видим, что после команды «sleep» больше ничего не выполняется.Проведя несколько тестов, я пришел к выводу, что мой скрипт останавливается, как только ключ смонтирован, и я ничего не могу сделать, когда ключ смонтирован.

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

Поэтому я установил следующее правило, которое мне немного сложнее понять, но результат точно такой же:

KERNEL!="sd[a-z]*", GOTO="media_by_label_auto_mount_end" ACTION=="add", PROGRAM!="/sbin/blkid %N", GOTO="media_by_label_auto_mount_end"

# Get label
PROGRAM=="/sbin/blkid -o value -s LABEL %N", ENV{dir_name}="%c"

# use basename to correctly handle labels such as ../mnt/foo
PROGRAM=="/usr/bin/basename '%E{dir_name}'", ENV{dir_name}="%c" ENV{dir_name}=="", ENV{dir_name}="usbhd-%k"

ACTION=="add", ENV{dir_name}!="", RUN+="/bin/su tuxin -c '/usr/bin/pmount %N %E{dir_name}'", RUN+="/home/tuxin/insert-usbkey.sh"

ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/su tuxin -c '/usr/bin/pumount /media/%E{dir_name}'"

LABEL="media_by_label_auto_mount_end"

Скрипт работает правильно, когда он запускается вручную, но выполняется udev, как только ключ смонтирован, мне кажется, что он убит.Как я могу делать то, что я хочу, работать с ключом после автоматического определения монтирования?

Вот краткая информация о машинах, на которых этот скрипт был протестирован (с или без фоновых операций).Осталось понять, почему это не работает в Linux Mint.

  Distribution    udev version   Result
  -------------------------------------
  Linux Mint 18       229          KO
  L.M.D.E.            215          OK
  Poky custom.        182          OK
  Linux Mint 18       229          KO
  Lubuntu 18.04       237          OK

1 Ответ

0 голосов
/ 10 февраля 2019

Ваш тестовый скрипт выполняет свою основную логику в фоновой подоболочке .Поэтому он завершается почти сразу после запуска подоболочки, поэтому родительский процесс bash покорно сигнализирует обо всех дочерних процессах, уничтожая подоболочку, прежде чем он сможет что-то сделать.Следующее прекрасно работает с udev в моей системе:

#!/bin/bash
exec </dev/null >/tmp/key-inserted.log 2>&1; PS4=':$LINENO+'; set -x

KEY_LABEL="DEV_JP"

cd /media/tuxin || exit

for ((retries=0; retries<10; retries++)); do
  [[ -d "$KEY_LABEL" ]] && grep -q -e "$KEY_LABEL" /proc/mounts && break
  sleep 1
done
cd "$KEY_LABEL" || exit
ls .  # Double-check by listing the drive's contents
echo "SUCCESS"

Также обратите внимание, что я изменил ваш continue на break, потому что это именно то, что вы хотите сделать, когда нашли то, что искалидля: разрыв из цикла .

...