Автоматически подключать внешние диски к /media/LABEL при загрузке без входа пользователя?
Этот вопрос похож, но как бы противоположен тому, что я хочу. Я хочу, чтобы внешние USB-накопители автоматически монтировались при загрузке без входа в такие места, как /media/<label>
,
Я не хочу вводить все данные в fstab, отчасти потому, что это утомительно и раздражающе, но в основном потому, что я не могу предсказать, что я подключу к нему или как изменятся разделы в будущем.
Я хочу, чтобы диски были доступны для таких вещей, как MPD, и были доступны при входе в систему по SSH. gnome-mount
кажется, монтирует вещи только когда вы локально вошли в графический сеанс Gnome.
11 ответов
- Note for Ubuntu Server 11.10: This script fails on Ubuntu Server 11.10 due to the obsolete
vol_id
команда.vol_id
has been superseded byblkid
, To fix the script, replace "vol_id" by "blkid -o udev" in theudev-auto-mount.sh
скрипт.
I've been banging my head around this for a while now, and I think I've found a working solution. This is developed and tested on a Debian-based system, so it should work on Ubuntu. I'll point out the assumptions it makes so it can be adapted to other systems as well.
- It will automatically mount USB drives on plugin, and shouldn't take much to adapt for Firewire.
- It uses UDEV, so no monkeying with HAL/DeviceKit/GNOME-Anything.
- It automagically creates a
/media/LABEL
directory to mount the device to. - However, it may interfere with other automounters; I can't test for that. I expect that, with Gnome-VFS active, both may try to do the mount... if Gnome-VFS fails the mount, it might not configure a desktop icon. Unmounting from Gnome should be possible, but might require
gksudo
or similar.
I have not tested this on system boot, but the only reason I can see that it might not work is if it tries to mount the USB drive before the system is ready for mounts. If that's the case, you'll probably need one additional tweak to the mount script. (I'm checking with ServerFault to see if there's any advice, but not much interest in it over there.)
On to it, then.
UDEV references:
- Writing udev Rules (the reference for udev rules)
- man udev (see your system for the latest version)
- man udevadm (udev admin tool; again see your system for latest)
- Backup to USB drive on mount (completely different problem, but helpful for understanding the solution)
Background (UDEV? Whuzzat?)
UDEV is the kernel's hotplug system. It's what automagically configures the proper devices and device symlinks (eg /dev/disk/by-label/<LABEL>
), both at boot time and for devices added while the system is running.
D-Bus and HAL are used for sending hardware events to listeners like Desktop Environments. So when you log into GNOME and insert a CD or plug in a USB drive, that event follows this chain:
kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount)
And presto, your drive gets mounted. But in a headless system, we don't want to have to log in to get the benefits of automounting.
Udev Rules
Since UDEV lets us write rules and run programs on device insertion, this is an ideal choice. We're going to take advantage of Debian/Ubuntu's existing rules, let them setup the /dev/disk/by-label/<LABEL>
symlink for us, and add another rule that will mount the device for us.
UDEV's rules are kept in /etc/udev/rules.d
(а также /lib/udev/rules.d
on Karmic), and are processed in numerical order. Any file not starting with a number gets processed after the numbered files. On my system, HAL rules are in a file called 90-hal.rules
, so I put my rules in 89-local.rules
so they get processed before they get to HAL. Primarily, you need to make sure these rules happen after the 60-persistent-storage.rules
, local.rules
может быть достаточно хорош
Поместите это в ваш новый файл правил:
# /etc/udev/rules.d/local.rules
# /etc/udev/rules.d/89-local.rules
# ADD rule: if we have a valid ID_FS_LABEL_ENC, and it's USB, mkdir and mount
ENV{ID_FS_LABEL_ENC}=="?*", ACTION=="add", SUBSYSTEMS=="usb", \
RUN+="/usr/local/sbin/udev-automounter.sh %k"
Убедитесь, что после
\
простоnewline
(\n
).+ Изменить
SUBSYSTEMS=="usb"
вSUBSYSTEMS=="usb|ieee1394"
для поддержки Firewire.Если вы хотите, чтобы устройство всегда принадлежало определенному пользователю, добавьте
OWNER="username"
пункт. Если вам просто нужны файлы, принадлежащие конкретному пользователю, вместо этого настройте скрипт монтирования.
Чтение правила
Это добавляет программу для запуска в список программ устройства для запуска. Он идентифицирует устройства USB-разделов по <LABEL>
, а затем передает эту информацию в скрипт, который выполняет монтирование. В частности, это правило соответствует:
ENV{ID_FS_LABEL_ENC}=="?*"
- переменная окружения, установленная более ранним системным правилом. Не существует для не файловых систем, поэтому мы проверяем это. Мы на самом деле хотим использоватьID_FS_LABEL
для точки монтирования, но я не убедил UDEV избежать его для меня, поэтому мы позволим сценарию монтирования обработать это.Эта и другие переменные окружения получаются с помощью
vol_id
команда ( устарела). Это удобный инструмент, чтобы увидеть приятные быстрые детали на разделе:$ sudo vol_id /dev/sdc1 ID_FS_TYPE=ext2 ID_FS_UUID=a40d282a-4a24-4593-a0ab-6f2600f920dd ID_FS_LABEL=Travel Dawgs ID_FS_LABEL_ENC=Travel\x20Dawgs ID_FS_LABEL_SAFE=Travel_Dawgs
ACTION=="add"
- только матчadd
События...SUBSYSTEMS=="usb"
- сопоставлять только устройства, которые находятся на шине USB. Мы используемSUBSYSTEMS
здесь, потому что это совпадает с родителями нашего устройства; интересующее нас устройство на самом деле будет SUBSYSTEM=="scsi". Сопоставление с родительским USB-устройством позволяет избежать добавления нашей программы во внутренние накопители.RUN+="..."
- не совпадение, а действие: добавьте эту программу в список программ для запуска. В аргументах программы%k
расширяется до имени устройства (например,sdc1
не/dev/sdc1
) а также$env{FOO}
получает содержимое переменной окружения FOO.
Тестирование правила
Первая ссылочная ссылка (выше) - отличное руководство по UDEV, но оно немного устарело. Программы, которые он запускает для проверки ваших правил (udevtest
в частности) были заменены всеохватывающие udevadm
полезность.
После того, как вы добавили правило, подключите ваше устройство. Дайте ему несколько секунд, затем проверьте, на какое устройство ему назначено:
$ ls -l /dev/disk/by-label/*
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Foo -> ../../sda1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Bar -> ../../sdb1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Baz -> ../../sdc1
Если ваш съемный диск содержит label_Baz
это на устройстве sdc1
, Запустите это и посмотрите на вывод в конце:
$ sudo udevadm test /sys/block/sdc/sdc1
parse_file: reading (...) (many lines about files it reads)
import_uevent_var: import into environment: (...) (many lines about env variables)
(...) (many lines tracing rule matches & programs run)
update_link: found 1 devices with name 'disk/by-label/LABEL_BAZ'
update_link: found '/block/sdc/sdc1' for 'disk/by-label/LABEL_BAZ'
update_link: compare (our own) priority of '/block/sdc/sdc1' 0 >= 0
update_link: 'disk/by-label/LABEL_BAZ' with target 'sdc1' has the highest priority 0, create it
udevtest: run: '/usr/local/sbin/udev-automounter.sh sdc1 LABEL_BAZ'
udevtest: run: 'socket:/org/freedesktop/hal/udev_event'
udevtest: run: 'socket:@/org/kernel/udev/monitor'
Ищите название скрипта из нашего RUN+=
правило в последних нескольких строках (3-е снизу в этом примере). Вы можете увидеть аргументы, которые будут использоваться для этого устройства. Вы можете запустить эту команду сейчас, чтобы проверить правильность аргументов; если он работает в командной строке, он должен работать автоматически при вставке устройства.
Вы также можете отслеживать события UDEV в режиме реального времени: запустить sudo udevadm monitor
(увидеть man udevadm
для деталей на выключателях). Затем просто подключите новое устройство и наблюдайте за прокруткой событий. (Вероятно, излишне, если вы не в мелочах...)
Перезагрузка правил
После того, как вы убедились, что правило читается правильно, вам нужно сказать UDEV перезагрузить его правила, чтобы новое вступило в силу. Используйте любой из этих методов (если первый не работает, второй должен... но попробуйте первый первый):
бежать
sudo udevadm control --reload-rules
бежать
sudo /etc/init.d/udev reload
перезагружать
Сценарий! На самом деле, 2 сценария...
Вот первый сценарий. Поскольку программа, которую мы запускаем, должна быстро завершиться, это просто раскручивает второй скрипт в фоновом режиме. Поместите это в /usr/local/sbin/udev-automounter.sh
:
#!/bin/sh
#
# USAGE: usb-automounter.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
/usr/local/sbin/udev-auto-mount.sh ${1} &
Вот второй сценарий. Это немного больше проверяет ввод. Поместите это в /usr/local/sbin/udev-auto-mount.sh
, Вы можете настроить параметры монтирования ниже. Этот скрипт теперь самостоятельно обрабатывает раздел LABEL; UDEV только отправляет имя УСТРОЙСТВА.
Если при загрузке возникает проблема с подключением дисков, вы можете sleep 60
в этом сценарии, чтобы дать системе время полностью пройти до того, как сценарий попытается смонтировать диск.
Я дал предложение в комментариях о том, как проверить (запустить ps
чтобы увидеть, работает ли веб-сервер), но вы захотите настроить его для своей системы. Я думаю, что для этой цели подойдет большинство любых сетевых серверов, которые вы могли бы использовать - nfsd, smbd, apache и т. Д. Риск, конечно, состоит в том, что скрипт монтирования завершится неудачно, если служба не запущена, поэтому, возможно, тестирование существование конкретного файла было бы лучшим решением.
#!/bin/sh
#
# USAGE: udev-auto-mount.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
#
# This script takes a device name, looks up the partition label and
# type, creates /media/LABEL and mounts the partition. Mount options
# are hard-coded below.
DEVICE=$1
# check input
if [ -z "$DEVICE" ]; then
exit 1
fi
# test that this device isn't already mounted
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
echo "error: seems /dev/${DEVICE} is already mounted"
exit 1
fi
# If there's a problem at boot-time, this is where we'd put
# some test to check that we're booting, and then run
# sleep 60
# so the system is ready for the mount below.
#
# An example to experiment with:
# Assume the system is "booted enough" if the HTTPD server is running.
# If it isn't, sleep for half a minute before checking again.
#
# The risk: if the server fails for some reason, this mount script
# will just keep waiting for it to show up. A better solution would
# be to check for some file that exists after the boot process is complete.
#
# HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# while [ -z "$HTTPD_UP" ]; do
# sleep 30
# HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# done
# pull in useful variables from vol_id, quote everything Just In Case
eval `/sbin/vol_id /dev/${DEVICE} | sed 's/^/export /; s/=/="/; s/$/"/'`
if [ -z "$ID_FS_LABEL" ] || [ -z "$ID_FS_TYPE" ]; then
echo "error: ID_FS_LABEL is empty! did vol_id break? tried /dev/${DEVICE}"
exit 1
fi
# test mountpoint - it shouldn't exist
if [ ! -e "/media/${ID_FS_LABEL}" ]; then
# make the mountpoint
mkdir "/media/${ID_FS_LABEL}"
# mount the device
#
# If expecting thumbdrives, you probably want
# mount -t auto -o sync,noatime [...]
#
# If drive is VFAT/NFTS, this mounts the filesystem such that all files
# are owned by a std user instead of by root. Change to your user's UID
# (listed in /etc/passwd). You may also want "gid=1000" and/or "umask=022", eg:
# mount -t auto -o uid=1000,gid=1000 [...]
#
#
case "$ID_FS_TYPE" in
vfat) mount -t vfat -o sync,noatime,uid=1000 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
# I like the locale setting for ntfs
ntfs) mount -t auto -o sync,noatime,uid=1000,locale=en_US.UTF-8 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
# ext2/3/4 don't like uid option
ext*) mount -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
esac
# all done here, return successful
exit 0
fi
exit 1
Супер бонус сценарий очистки!
Еще один скрипт. Все это делает размонтирование устройства и удаление каталогов точки монтирования. Предполагается, что для этого у него есть привилегии, поэтому вам нужно запустить его с sudo
, Этот скрипт теперь принимает полную точку монтирования в командной строке, например:
$ /usr/local/sbin/udev-unmounter.sh "/media/My Random Disk"
Поместите это в /usr/local/sbin/udev-unmounter.sh
:
#!/bin/sh
#
# USAGE: udev-unmounter.sh MOUNTPT
# MOUNTPT is a mountpoint we want to unmount and delete.
MOUNTPT="$1"
if [ -z "$MOUNTPT" ]; then
exit 1
fi
# test mountpoint - it should exist
if [ -e "${MOUNTPT}" ]; then
# very naive; just run and pray
umount -l "${MOUNTPT}" && rmdir "${MOUNTPT}" && exit 0
echo "error: ${MOUNTPT} failed to unmount."
exit 1
fi
echo "error: ${MOUNTPT} does not exist"
exit 1
Последний вариант, который другие предложили в сети, это ivman
, но это, кажется, зависит от pmount
, который вы уже заявили, не работает. pmount
заброшен и ivman
почти то же самое.
Замена для ivman
является halevt
и это доступно на кармическом. Это перевоплощение ivman
(читай: "поддерживается" и "не зависит от pmount"). Пакет недоступен в Jaunty, хотя вы можете создать его самостоятельно, если не планируете обновление.
Оба эти инструмента находятся над уровнями DBus и HAL и отвечают на события от них. Очевидно, что оба могут работать как системный демон или как менеджер монтирования сеанса пользователя (как Gnome-VFS) - /etc/defaults/{ivman,halevt}
файлы отвечают за настройки системы.
Вот несколько инструкций по настройке ivman
использовать /media/<LABEL>
слишком длинные. Вероятно, что halevt
есть более простой способ сделать это, но, возможно, они помогут вам найти ответ.
Работа с HALEVT
Обновление: чтобы получить автоматическое монтирование компакт-дисков, чего не дает мой ответ UDEV, я посмотрел глубже halevt
, Я нашел этот пост в блоге, который помог объяснить многое о процессе. Я должен был собрать свой собственный halevt
пакет для Debian Lenny (к счастью, все зависимости были в разделе lenny-backports). После установки процесс был в основном не-ужасным:
- Убедитесь, что система halevt-daemon включена в
/etc/default/halevt
- Разрешить пользователю системы монтировать устройства в
/etc/PolicyKit/PolicyKit.conf
(см. ниже; источник) - Измените политику HAL, чтобы скопировать метку тома в предпочтительную точку монтирования в
/etc/hal/fdi/policy/preferences.fdi
(увидеть ниже) - Если вам нужна поддержка CD/DVD, возьмите
eject.hal
Сценарий из вышеупомянутого поста блога, изменить и сохранить в/usr/local/bin
, - Измените конфигурацию системы halevt, чтобы включить монтирование в
/etc/halevt/halevt.xml
- Добавьте код в сценарии до и после сеанса вашего менеджера входа, чтобы остановить системный демон halevt при входе в систему, и перезапустить его при выходе из системы.
Если вам нужно перезапустить демоны HAL и HALEVT, чтобы проверить ваши новые конфигурации, используйте это, чтобы получить их в правильном порядке:
sudo sh -c "/etc/init.d/halevt stop ; /etc/init.d/hal restart ; /etc/init.d/halevt start"
Шаг 1
Проверь это START_DAEMON=yes
в /etc/default/halevt
,
Шаг 2
В /etc/PolicyKit/PolicyKit.conf
добавь это внутрь <config></config>
раздел:
<match action="org.freedesktop.hal.storage.mount-removable">
<match user="halevt">
<return result="yes"/>
</match>
</match>
Шаг 3
В /etc/hal/fdi/policy/preferences.fdi
добавьте это внутри раздела `
<match key="volume.label" empty="false">
<match key="volume.label" is_absolute_path="false">
<merge key="volume.policy.desired_mount_point" type="copy_property">volume.label</merge>
</match>
</match>
Шаг 4
Сценарий хорош, но должен работать /bin/bash
; некоторые системы могут фактически использовать /bin/dash
когда /bin/sh
называется. Поэтому измените верхнюю строку в скрипте, чтобы убедиться, что вы получите правильную:
#!/bin/sh <------ old first line
#!/bin/bash <------ new first line
Шаг 5
Это самая веселая часть. Ваша система может предоставить основные /etc/halevt/halevt.xml
уже, так что вам придется адаптировать это для собственного использования. В моем случае моя система уже обеспечивала базовую установку съемных устройств, но мне пришлось добавить поддержку для монтажа на CDROM и кнопку извлечения.
В блоге, о котором я упоминал, есть хороший пример конфигурации XML, на который можно посмотреть для ваших собственных настроек. В основном речь идет о настройке замены gnome-mount для автора fluxbox
среда, поэтому его пример XML делает больше, чем вы хотите, но это отличный способ понять, что вы можете сделать. Есть также несколько хороших примеров в /usr/share/doc/halevt/examples
,
Я также должен был бежать sudo sh -c "mkdir /var/halevt ; chown halevt:plugdev /var/halevt"
прежде чем все будет работать.
Вот мои дополнения, чтобы сделать автоматическое подключение CD/DVD:
<!-- CD/DVD mount -->
<halevt:Device match="hal.block.device & hal.block.is_volume = true & hal.volume.is_disc = true & hal.volume.disc.has_data = true">
<halevt:Property name="hal.volume.is_mounted">
<halevt:Action value="true" exec="halevt-mount -u $hal.udi$ -p $hal.volume.policy.desired_mount_point$ -m 002"/>
</halevt:Property>
</halevt:Device>
<!-- CD/DVD eject button support -->
<halevt:Device match="hal.storage.drive_type = cdrom">
<halevt:Condition name="EjectPressed" exec='/usr/local/bin/eject.hal $hal.block.device$'/>
</halevt:Device>
Шаг 6
После того, как вы запустили систему halevt-daemon, вам нужно отключить ее при входе в GNOME и перезапустить снова при выходе. (См. Мой ответ на этот вопрос для менеджеров входа не в GDM.) Это теоретический материал, поскольку я им не пользуюсь, но он должен работать.
В /etc/gdm/PreSession/Default
, добавьте это, чтобы остановить систему halevt-daemon:
/etc/init.d/halevt stop
В /etc/gdm/PostSession/Default
, добавьте это, чтобы перезапустить систему halevt-daemon:
/etc/init.d/halevt start
Со временем появляются более простые решения.
Это решение основано на программном пакете udevil, который был написан для этой цели, и не требует вмешательства в правила udevil. Это, вероятно, предпочтительнее (для новых и старых пользователей) в качестве простого решения.
devmon
Скрипт от Udevil делает все волшебство, в то время как только в зависимости от Udev и Glib. Работает практически из коробки без необходимости начальной настройки.
Все, что я делал на своей рабочей станции, это вызывал devmon из rc.local
как это:devmon 2>&1 >> /var/log/devmon &
Для вашего удобства вы можете включить это в сценарий инициализации вместо rc.local
используя автоматизированный инструмент, такой как pleaserun
чтобы создать его: https://unix.stackexchange.com/a/124609/42673
После его запуска проверяется хранилище, которое я подключаю (он ищет разделы и, если найден, смотрит на метки их файловой системы), а затем монтируется в /media/FILESYSTEM_LABEL
,
Невозможно представить что-нибудь более простое, чем это, за исключением, может быть, того, что (в) известной системе будет внедрена эта функция в будущем.
Udevil с первого взгляда ( http://ignorantguru.github.io/udevil/)
Скрипт: devmon ( igurublog / script-devmon)
Чтобы вытащить отличные инструкции Quackote Quixote для удаления:
Добавьте следующую строку в файл правил udev, который вы сделали ранее (/etc/udev/rules.d)"
ENV{ID_FS_LABEL_ENC}=="?*", ACTION=="remove", SUBSYSTEMS=="usb", \
RUN+="/usr/local/sbin/udev-autounmounter.sh %k"
Затем создайте следующий скрипт и выполните его исполняемый файл (/usr/local/sbin/udev-autounmounter.sh) со следующим содержимым:
#!/bin/sh
#
# USAGE: usb-autounmounter.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
/usr/local/sbin/udev-auto-unmount.sh ${1} &
Наконец, сам сценарий размонтирования (udev-auto-unmount.sh):
#!/bin/sh
#
# USAGE: udev-auto-unmount.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
#
# This script takes a device name, looks up the partition label and
# type, creates /media/LABEL and mounts the partition. Mount options
# are hard-coded below.
DEVICE=$1
# check input
if [ -z "$DEVICE" ]; then
exit 1
fi
#test that the device is already mounted
MOUNTPT=`mount | grep ${DEVICE} | cut -d ' ' -f 3`
if [ -z "${MOUNTPT}" ]; then
echo "error: the device is not already mounted"
exit 1
fi
# test mountpoint - it should exist
if [ -e "${MOUNTPT}" ]; then
# very naive; just run and pray
umount -l "${MOUNTPT}" && rmdir "${MOUNTPT}" && exit 0
echo "error: ${MOUNTPT} failed to unmount."
exit 1
fi
echo "error: ${MOUNTPT} does not exist"
exit 1
Таким образом, с другими инструкциями каталог будет автоматически появляться и исчезать при событиях udev.
Ответ кряква не работает на Ubuntu Lucid Lynx (10.04) - нет /sbin/vol_id
команда.
Вместо того, чтобы придумывать и использовать udev, поместите это в ваш /etc/rc.local и выполните:
for dev in $(ls -1 /dev/disk/by-label/* | grep -v EFI) ; do
label=$(basename $dev)
mkdir -p /media/$label
$(mount | grep -q /media/$label) || mount $dev /media/$label
done
Для систем на основе Debian (например, Ubuntu и т. Д.) Есть пакет usbmount, который автоматически подключает USB-накопители. Он в основном использует подход, основанный на udev, как уже было изложено, - это всего лишь простая установка пакета. Кажется, первоначальный автор пакета исчерпал себя, но Ubuntu/Debian все еще поддерживает его (я думаю, что это не так сложно) - так что он все еще доступен в последних выпусках.
Установленные сценарии можно настроить (/etc/usbmount/usbmount.conf) для предоставления соответствующих точек монтирования.
Вы можете попробовать положить su username -c gnome-volume-manager
в /etc/rc.local. Этого может быть достаточно, чтобы просто запустить gnome-volume-manager.
Изменить: Кажется, что gnome-volume-manager больше не является частью дистрибутива по умолчанию, даже на рабочем столе Ubuntu.
wajig policy gnome-volume-manager
gnome-volume-manager:
Installed: (none)
Candidate: 2.24.0-0ubuntu1
Version table:
2.24.0-0ubuntu1 0
500 http://ubuntu.secs.oakland.edu jaunty/universe Packages
Однако, возможно, если вы установите его, он все равно будет работать. Стоит попробовать. Если это не работает, удалите его снова.
Там также usbmount
пакет, который делает то, что вы хотите, но может помешать нормальному автомонтированию.
Мои отредактированные дополнения для решения на основе udev от Quack Quixote были отклонены, поэтому я собираюсь разместить их здесь. Пожалуйста, обратитесь к его сообщению в первую очередь.
Прежде всего, если вы хотите, чтобы правило udev действовало, когда какое-либо устройство подключено через подсистему SCSI (которая включает в себя как USB, FireWire и eSATA), измените соответствие SUBSYSTEMS в правиле udev на SUBSYSTEMS=="scsi"
,
Имейте в виду, однако, что это автоматически подключит почти все, включая внутренние диски, если вы подключите их к сети во время работы системы, так что это может быть не тем, что вы хотите.
Во-вторых, вот сценарий, который я использую, который заменяет все сценарии в этом посте. Он также автоматически очищает созданные точки монтирования в / media /, как только удаленное смонтированное блочное устройство удаляется - нет необходимости в ручном вмешательстве. Кроме того, вместо вызова другого сценария для запуска в фоновом режиме, он помещает себя в фоновый режим, когда он не выполняется с терминала (например, когда выполняется с помощью udev).
Он использует inotifywait для ожидания исчезновения смонтированного устройства, а затем удаляет созданный каталог. Поэтому в вашей системе должны быть установлены inotify-tools. На дистрибутивах на основе Debian (включая Ubuntu), sudo apt-get install inotify-tools
должно хватить.
#!/bin/bash
#
# Auto-mounter script, to be executed by udev on the addition of a
# mass storage device.
#
# Takes one argument; the base block device partition, e.g. "sdb3".
#
# Creates a mountpoint for the partition using its FS label, in
# /media/{fslabel} and mounts it there, read-only, unsynced.
#
# If the filesystem has no label, "Untitled" is used instead.
#
# If another filesystem is already mounted at that location, the
# newcomer will be mounted with an integer number appended to its
# label.
MOUNT_OPTS="ro,noatime,nodiratime"
# If we're called from a non-tty and not explicitly told to continue,
# we call ourselves in a subshell and thus return immediately (udev
# gets impatient):
if [[ "$2" != "backgrounded" ]] && ! tty &> /dev/null; then
($0 $1 backgrounded &)
exit
fi
# Determine the desired mountpoint from the label of the fs on the partition:
MOUNTPOINT="/media/$(blkid /dev/$1 | grep LABEL | sed -E 's:^.+LABEL="([^"]+).+:\1:')"
# If it had no label, use "Untitled":
[[ "$MOUNTPOINT" = "/media/" ]] && MOUNTPOINT="/media/Untitled"
# If something's already mounted there, append a number:
if [[ -e "$MOUNTPOINT" ]] && mountpoint "$MOUNTPOINT" &> /dev/null; then
NUM=1
while mountpoint "$MOUNTPOINT $NUM" &> /dev/null; do NUM=$((NUM+1)); done
MOUNTPOINT="$MOUNTPOINT $NUM"
fi
# Create the mountpoint and mount there:
mkdir "$MOUNTPOINT" && mount -o $MOUNT_OPTS /dev/$1 "$MOUNTPOINT"
# Wait until the device is removed (the block device is "deleted"):
inotifywait -e delete /dev/$1
# Then clean up. If it fails, retry every second for up to 5 mins:
TRIES=0
while [[ -e "$MOUNTPOINT" ]] && [[ $TRIES -lt 300 ]]; do
rmdir "$MOUNTPOINT"
sleep 1s
TRIES=$((TRIES+1))
done
Вы заметите, что я монтирую устройства без синхронизации и только для чтения. Это потому, что в 99% случаев мой вариант использования - это чтение с внешнего диска, и всякий раз, когда мне нужно записать на него, я все равно буду активен на сервере и легко могу mount -o remount,rw <mountpoint>
команда. Изменить в соответствии с вашими потребностями:)
Попробуйте настроить через mountmanager, чтобы вам не приходилось вводить данные вручную.
Это должно быть частью репозитория Ubuntu.
Если у вас одновременно установлен только один диск, вы можете просто отредактировать его в своем /etc/fstab
файл. Что-то вроде:
/dev/sdb1 /mnt/usbdrive ext3 defaults 0 0
Это должно смонтировать его при загрузке и сделать его доступным для всех, у кого есть права доступа. Если у вас есть более одного диска, вы можете сделать это с:
/dev/sdb1 /mnt/usbdrive1 ext3 defaults 0 0
/dev/sdc1 /mnt/usbdrive2 ext3 defaults 0 0