Привязка скрипта к udev для создания ссылки на /run/user
Я пытаюсь создать ссылку на папку mtp в папке /run/user/$UID/gvfs/. Я написал скрипт для выполнения, в том числе несколько строк для проверки правильности работы скрипта. Я связал udev с правилом на /etc/udev/rules.d. Скрипт работает правильно, когда я запускаю его с обычным пользователем, но не работал при работе с правами root (не с разрешения!!). Я пытался выполнить скрипт как обычный пользователь (используя sudo -u user, su user, runuser user...) Но ничего не работает! Я проверил в файле журнала, что сценарий на самом деле выполняется, но не имеет пользователя и создает неисправную ссылку.
Любая идея??
/etc/udev/rules.d/85-automount.rules:
ACTION=="add",SUBSYSTEM=="usb",ATTR{idVendor}=="04e8",ATTR{idProduct}=="6860", RUN+="sudo -u sphere /usr/local/bin/android_mount"
Автор сценария:
#!/bin/bash
LOGFILE="/home/sphere/log/android_mount.log"
i=1
for mtp_folder in $( ls -d /run/user/1000/gvfs/mtp*);
do
# Remove previous link
rm -f "/media/sphere/mtp$i"
# Create new link
OUT=$(ln -s $mtp_folder /media/sphere/mtp$i 2>&1)
# Notify error
if [[ -z $OUT ]]; then
echo "$(date) - $OUT" >> $LOGFILE
fi
i=$(($i+1))
done
echo "$(date) - Script executed as user=$USER" >> $LOGFILE
1 ответ
Я могу предположить проблему: используя правило udev, ваш скрипт запускается до того, как слой gvfs даже видит устройство, тем более что у него есть шанс его автоматически смонтировать.
Идея udev заключается в том, что он сначала получает "события" от ядра, обрабатывает их в соответствии с правилами, а затем ретранслирует их всем остальным программам. (Хотя другие приложения также могут получать эти события напрямую, это редко делается, поскольку обработанные имеют гораздо больше информации и гарантированно будут отправлены только тогда, когда устройство будет готово к использованию.)
Другими словами, gvfs даже не получает информацию об устройстве до тех пор, пока не запустится ваш скрипт.
И если вы захотите что-то сделать после того, как gvfs установит его, вам придется реагировать на события,которые отправляет gvfs. Вместо правила udev вам понадобится скрипт, который использует D-Bus и прослушивает сигналы на сеансовой шине. Начать с dbus-monitor --session
или же busctl monitor --user
чтобы узнать, что отправлено, используйте модули Perl или Python D-Bus для обработки.
Как примечание стороны, вместо for var in $(ls -d /some/path*)
, вы можете получить тот же результат, просто используя for var in /some/path*
, Не ls расширяет символы подстановки - это сама оболочка.