- Ubuntu Server 11.10 참고 : 이 스크립트는 사용되지 않는
vol_id
명령 으로 인해 Ubuntu Server 11.10에서 실패합니다 . vol_id
님이 대신했습니다 blkid
. 스크립트를 수정하려면 스크립트에서 "vol_id"를 "blkid -o udev"로 바꾸십시오 udev-auto-mount.sh
.
나는 이것에 대해 잠시 동안 내 머리를 두드리고 있었고, 나는 해결책을 찾았다 고 생각한다. 이것은 데비안 기반 시스템에서 개발 및 테스트되었으므로 우분투에서 작동합니다. 다른 시스템에도 적용 할 수있는 가정을 지적하겠습니다.
- 플러그인에 USB 드라이브를 자동으로 마운트하므로 Firewire에 적응하는 데 많은 시간이 걸리지 않습니다.
- UDEV를 사용하므로 HAL / DeviceKit / GNOME-Anything을 사용하는 원숭이가 없습니다.
- 자동으로
/media/LABEL
장치를 마운트 할 디렉토리를 만듭니다 .
- 그러나 다른 자동 마운터를 방해 할 수 있습니다 . 나는 그것을 테스트 할 수 없습니다. Gnome-VFS가 활성화되어 있으면 둘 다 마운트를 시도 할 수 있습니다. Gnome-VFS가 마운트에 실패하면 데스크탑 아이콘을 구성하지 않을 수 있습니다. 그놈에서 마운트 해제가 가능해야하지만 필요
gksudo
하거나 유사 할 수 있습니다 .
시스템 부팅시 이것을 테스트하지는 않았지만 시스템이 마운트 준비가되기 전에 USB 드라이브를 마운트하려고 시도하는 것이 작동하지 않을 수있는 유일한 이유입니다. 이 경우 마운트 스크립트를 한 번 더 조정해야 할 수도 있습니다. (나는 조언이 있는지 확인하기 위해 ServerFault 를 확인하고 있지만 그에 대한 관심은별로 없습니다.)
그런 다음에.
UDEV 참조 :
배경 (UDEV? Whuzzat?)
UDEV는 커널의 핫 플러그 시스템입니다. /dev/disk/by-label/<LABEL>
부팅시와 시스템이 실행되는 동안 추가 된 장치에 대해 적절한 장치와 장치 심볼릭 링크 (예 :)를 자동으로 구성합니다 .
D-Bus 및 HAL은 데스크톱 환경과 같은 리스너에 하드웨어 이벤트를 보내는 데 사용됩니다. 따라서 그놈에 로그인하여 CD를 넣거나 USB 드라이브를 연결하면 다음과 같은 이벤트가 발생합니다.
kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount)
그리고 presto, 당신의 드라이브가 마운트됩니다. 그러나 헤드리스 시스템에서는 자동 마운팅의 이점을 얻기 위해 로그인 할 필요가 없습니다.
Udev 규칙
UDEV를 사용하면 장치 삽입시 규칙을 작성하고 프로그램을 실행할 수 있으므로 이상적인 선택입니다. 데비안 / 우분투의 기존 규칙을 활용하여 /dev/disk/by-label/<LABEL>
심볼릭 링크를 설정 하고 장치를 마운트 할 다른 규칙을 추가하겠습니다.
UDEV의 규칙은 /etc/udev/rules.d
(및 /lib/udev/rules.d
Karmic에) 유지 되며 숫자 순서대로 처리됩니다. 숫자로 시작하지 않는 파일은 번호가 매겨진 파일 다음에 처리됩니다. 내 시스템에서 HAL 규칙은이라는 파일 90-hal.rules
에 89-local.rules
있으므로 HAL에 도달하기 전에 처리되도록 규칙을 넣습니다 . 기본적으로이 규칙이 다음에 발생하는지 확인해야합니다 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"
파이어 와이어 지원.
특정 사용자가 항상 장치를 소유하려면 OWNER="username"
조항을 추가하십시오 . 특정 사용자가 소유 한 파일이 필요한 경우 대신 마운트 스크립트를 조정하십시오.
규칙을 읽고
이것은 실행할 프로그램을 장치의 프로그램 목록에 추가합니다. 로 USB 파티션 장치를 식별 <LABEL>
한 다음이 정보를 마운트를 수행하는 스크립트로 전달합니다. 특히이 규칙은 다음과 일치합니다.
ENV{ID_FS_LABEL_ENC}=="?*"
-이전 시스템 규칙에 의해 설정된 환경 변수 파일 시스템 이외의 시스템에는 존재하지 않으므로 확인해야합니다. 실제로 ID_FS_LABEL
마운트 지점 에 사용하고 싶지만 UDEV가 이스케이프를 이스케이프하도록 설득하지 않았으므로 마운트 스크립트에서 처리하도록하겠습니다.
이 환경 변수와 다른 환경 변수는 udev에서 vol_id
명령 ( deprecated )을 사용하여 얻습니다 . 파티션에 대한 빠른 세부 정보를 볼 수있는 편리한 도구입니다.
$ 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
not /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+=
마지막 몇 줄 (이 예에서는 아래에서 세 번째)에서 규칙에서 스크립트 이름을 찾으십시오 . 이 장치에 사용될 인수를 볼 수 있습니다. 이제 해당 명령을 실행하여 인수가 올바른지 확인할 수 있습니다. 명령 줄에서 작동하면 장치를 삽입 할 때 자동으로 작동합니다.
실시간으로 UDEV 이벤트를 모니터링 할 수도 있습니다. 실행 sudo udevadm monitor
( man udevadm
스위치에 대한 자세한 내용 은 참조 ). 그런 다음 새 장치를 연결하고 이벤트가 스크롤되는 것을 지켜보십시오. (실제로 낮은 수준의 세부 사항에 속하지 않는 한 아마 과잉 일 것입니다 ...)
규칙 재로드
규칙을 올바르게 읽고 있음을 확인한 후 UDEV에 규칙을 다시로드하도록 지시하여 새 규칙이 적용되도록해야합니다. 다음 방법 중 하나를 사용하십시오 (첫 번째 방법이 작동하지 않으면 두 번째 방법은 ...하지만 첫 번째 방법을 시도하십시오).
스크립트! 사실, 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는 DEVICE 이름 만 보냅니다.
부팅시 드라이브를 마운트하는 데 문제가있는 경우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