ติดตั้งไดรฟ์ภายนอกโดยอัตโนมัติเพื่อ / media / LABEL เมื่อบูตโดยไม่ต้องมีผู้ใช้เข้าสู่ระบบ?


73

คำถามนี้คล้ายกัน แต่ตรงข้ามกับสิ่งที่ฉันต้องการ ฉันต้องการไดรฟ์ USB /media/<label>ภายนอกที่จะติดตั้งโดยอัตโนมัติในการบูตโดยไม่มีใครเข้าสู่ระบบไปยังสถานที่เช่น

ฉันไม่ต้องการที่จะป้อนข้อมูลทั้งหมดลงใน fstab เพราะมันน่าเบื่อและน่ารำคาญ แต่ส่วนใหญ่เป็นเพราะฉันไม่สามารถคาดเดาได้ว่าฉันจะเสียบเข้าไปหรือไม่ว่าพาร์ติชันจะเปลี่ยนแปลงในอนาคตอย่างไร

ฉันต้องการให้ไดรฟ์สามารถเข้าถึงสิ่งต่าง ๆ เช่นMPDและพร้อมใช้งานเมื่อฉันเข้าสู่ระบบด้วย SSH gnome-mountดูเหมือนว่าจะเมานต์สิ่งต่าง ๆ เมื่อคุณเข้าสู่ระบบในเซสชั่นกราฟิก Gnome เท่านั้น


4
เป็นคำถามที่ดีหวังว่าฉันจะได้คำตอบสำหรับคุณตอนนี้ฉันอยากรู้ว่าวิธีการแก้ไขนี้
กลับ

1
ฉันปรับปรุงคำตอบของฉัน
Ryan Thompson

1
และสำหรับบันทึกนั้นฉันไม่มีปัญหากับ Gnome ที่กำลังติดตั้งเหมือนที่ฉันทำไปแล้ว แต่วิธีแก้ปัญหาสำหรับเซิร์ฟเวอร์ GUI ที่ไม่มีหัวขาดจะดีที่สุด
endolith

1
ARRRGHH ... บั๊กในคำตอบของฉัน ใน RUN ควรจะเป็น/usr/local/sbin/udev-automounter.sh mount %k /usr/local/sbin/udev-automounter.sh %kขอโทษ
ต้มตุ๋น Quixote

1
ตกลงเป็นของ Update-3 มันใช้งานได้กับช่องว่าง มันไม่ได้โดยใช้ "เข้ารหัส" รุ่น <label> ที่แปลงพื้นที่เข้า\x20's ดังนั้นมันจึงไม่สวย แต่จะใช้ได้ udev ไม่ได้จัดการป้ายกำกับพร้อมช่องว่างอย่างดี แต่มีตัวเลือกอื่นที่ใช้เครื่องหมายขีดล่างแทน\x20's (อย่างน้อยก็ดูดี) ดูเหมือนว่าการจัดการพื้นที่จะต้องเข้าไปใน shellscripts
ต้มตุ๋น Quixote

คำตอบ:


74
  • หมายเหตุสำหรับ Ubuntu Server 11.10:สคริปต์นี้ล้มเหลวบน Ubuntu Server 11.10 เนื่องจากvol_idคำสั่ง ล้าสมัย ได้ถูกแทนที่โดยvol_id blkidในการแก้ไขสคริปต์ให้แทนที่ "vol_id" โดย "blkid -o udev" ในudev-auto-mount.shสคริปต์

ฉันตีหัวของฉันรอบนี้มาระยะหนึ่งแล้วและฉันคิดว่าฉันได้พบวิธีแก้ปัญหาการทำงาน สิ่งนี้ได้รับการพัฒนาและทดสอบบนระบบที่ใช้เดเบียนดังนั้นมันจึงควรใช้กับ Ubuntu ฉันจะชี้ให้เห็นถึงสมมติฐานที่ทำให้มันสามารถปรับให้เข้ากับระบบอื่นเช่นกัน

  • มันจะติดตั้งไดรฟ์ USB บนปลั๊กอินโดยอัตโนมัติและไม่ควรปรับใช้กับ Firewire มากนัก
  • มันใช้ UDEV ดังนั้นอย่าลิงกับ HAL / DeviceKit / GNOME-Anything
  • มันสร้าง/media/LABELไดเรกทอรีเพื่อติดตั้งอุปกรณ์โดยอัตโนมัติ

  • อย่างไรก็ตามมันอาจรบกวนการเปิดประตูอัตโนมัติอื่น ๆ ฉันไม่สามารถทดสอบสิ่งนั้นได้ ฉันคาดหวังว่าด้วยการใช้งาน Gnome-VFS ทั้งคู่อาจลองเมานท์ ... หาก Gnome-VFS ไม่สามารถเมานต์ได้อาจไม่ได้กำหนดค่าไอคอนเดสก์ท็อป การถอนติดตั้งจาก Gnome ควรเป็นไปได้ แต่อาจต้องการgksudoหรือคล้ายกัน

ฉันยังไม่ได้ทดสอบสิ่งนี้ในการบู๊ตระบบ แต่เหตุผลเดียวที่ฉันเห็นว่ามันอาจไม่ทำงานคือหากพยายามเชื่อมต่อไดรฟ์ USB ก่อนที่ระบบจะพร้อมสำหรับการเมานต์ หากเป็นกรณีนี้คุณอาจต้องปรับแต่งสคริปต์เพิ่มเติมอีกหนึ่งรายการ (ฉันกำลังตรวจสอบกับ ServerFaultเพื่อดูว่ามีคำแนะนำใดบ้าง แต่ไม่สนใจเรื่องนั้นมากนัก)

เมื่อไปแล้ว


การอ้างอิง UDEV:


พื้นหลัง (UDEV? Whuzzat?)

UDEV เป็นระบบ hotplug ของเคอร์เนล มันคือสิ่งที่กำหนดค่าอุปกรณ์และ symlink ของอุปกรณ์ (เช่น/dev/disk/by-label/<LABEL>) โดยอัตโนมัติทั้งในเวลาบูตและสำหรับอุปกรณ์ที่เพิ่มในขณะที่ระบบกำลังทำงาน

D-Bus และ HAL ใช้สำหรับส่งกิจกรรมฮาร์ดแวร์ให้กับผู้ฟังเช่นสภาพแวดล้อมเดสก์ท็อป ดังนั้นเมื่อคุณเข้าสู่ GNOME และใส่แผ่นซีดีหรือเสียบในไดรฟ์ USB เหตุการณ์นั้นจะตามหลังสายโซ่นี้:

kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount)

และ presto, ไดรฟ์ของคุณได้รับการติดตั้ง แต่ในระบบไร้หัวเราไม่ต้องการเข้าสู่ระบบเพื่อรับประโยชน์จากการติดตั้งอัตโนมัติ

กฎ Udev

เนื่องจาก UDEV ช่วยให้เราสามารถเขียนกฎและเรียกใช้โปรแกรมในการแทรกอุปกรณ์ได้จึงเป็นตัวเลือกที่เหมาะสมที่สุด เราจะใช้ประโยชน์จากกฎที่มีอยู่ของ Debian / Ubuntu ปล่อยให้พวกเขาตั้งค่า/dev/disk/by-label/<LABEL>symlink ให้กับเราและเพิ่มกฎอื่นที่จะติดตั้งอุปกรณ์ให้เรา

กฎของ UDEV ถูกเก็บรักษาไว้ใน/etc/udev/rules.d(และ/lib/udev/rules.dKarmic) และถูกประมวลผลตามลำดับตัวเลข ไฟล์ใด ๆ ที่ไม่ได้ขึ้นต้นด้วยตัวเลขจะถูกประมวลผลหลังจากไฟล์ที่มีหมายเลข ในระบบของฉันกฎ 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"รองรับ Firewire

  • หากคุณต้องการให้อุปกรณ์เป็นเจ้าของโดยผู้ใช้เฉพาะเสมอให้เพิ่มส่วนOWNER="username"คำสั่ง หากคุณต้องการไฟล์ที่ผู้ใช้เฉพาะเป็นเจ้าของให้ปรับแต่งสคริปต์การเมาต์แทน

อ่านกฎ

เพิ่มโปรแกรมเพื่อเรียกใช้ในรายการโปรแกรมของอุปกรณ์ที่จะเรียกใช้ มันระบุอุปกรณ์พาร์ทิชัน USB โดย<LABEL>จากนั้นส่งผ่านข้อมูลนี้ไปยังสคริปต์ที่ดำเนินการติดตั้ง กฎนี้มีการจับคู่โดยเฉพาะ:

  1. ENV{ID_FS_LABEL_ENC}=="?*"- ตัวแปรสภาพแวดล้อมที่กำหนดโดยกฎของระบบก่อนหน้า ไม่มีอยู่สำหรับระบบไฟล์ที่ไม่ใช่ดังนั้นเราจึงตรวจสอบมัน เราต้องการใช้ID_FS_LABELสำหรับจุดเมานท์ แต่ฉันไม่ได้เชื่อ UDEV ให้หลบหนีเพื่อฉัน

    ตัวแปรสภาพแวดล้อมนี้และอื่น ๆ ได้รับโดย 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
    
  2. ACTION=="add"- จับคู่addเหตุการณ์เท่านั้น...

  3. SUBSYSTEMS=="usb"- จับคู่อุปกรณ์ที่อยู่บนบัส USB เท่านั้น เราใช้SUBSYSTEMSที่นี่เพราะสิ่งนี้ตรงกับพ่อแม่ของอุปกรณ์ของเรา อุปกรณ์ที่เราสนใจจะเป็นระบบย่อย == "scsi" การจับคู่กับอุปกรณ์ USB หลักหลีกเลี่ยงการเพิ่มโปรแกรมของเราไปยังไดรฟ์ภายใน

  4. RUN+="..."- ไม่ใช่การจับคู่ แต่เป็นการกระทำ: เพิ่มโปรแกรมนี้ในรายการโปรแกรมที่จะเรียกใช้ ในอาร์กิวเมนต์ของโปรแกรม%kรับขยายเป็นชื่ออุปกรณ์ (เช่นsdc1ไม่ใช่/dev/sdc1) และ$env{FOO}รับเนื้อหาของตัวแปรสภาพแวดล้อม FOO

ทดสอบกฎ

ลิงค์อ้างอิงแรก (ด้านบน) คือบทช่วย UDEV ที่ยอดเยี่ยม แต่มันล้าสมัยเล็กน้อย โปรแกรมที่ใช้สำหรับทดสอบกฎของคุณ ( udevtestโดยเฉพาะ) ได้ถูกแทนที่ด้วยudevadmยูทิลิตีcatch-all

หลังจากที่คุณเพิ่มกฎแล้วให้เสียบอุปกรณ์ของคุณ ให้เวลาสองสามวินาทีจากนั้นตรวจสอบเพื่อดูว่าอุปกรณ์ใดได้รับมอบหมายด้วย:

$ 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 จากด้านล่างในตัวอย่างนี้) คุณสามารถดูข้อโต้แย้งที่จะใช้สำหรับอุปกรณ์นี้ คุณสามารถเรียกใช้คำสั่งนั้นตอนนี้เพื่อตรวจสอบว่าข้อโต้แย้งนั้นเป็นเสียง ถ้ามันทำงานบน commandline ของคุณมันควรจะทำงานโดยอัตโนมัติเมื่อใส่อุปกรณ์

นอกจากนี้คุณยังสามารถตรวจสอบเหตุการณ์ UDEV แบบเรียลไทม์: เรียกใช้sudo udevadm monitor(ดูman udevadmรายละเอียดเกี่ยวกับสวิตช์) จากนั้นเพียงเสียบอุปกรณ์ใหม่แล้วดูการเลื่อนดูเหตุการณ์ (อาจ overkill เว้นแต่ว่าคุณจะลงรายละเอียดในระดับต่ำจริงๆ ... )

โหลดกฎใหม่

เมื่อคุณยืนยันว่ากฎกำลังอ่านอย่างถูกต้องคุณจะต้องบอก 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

สคริปต์การล้างข้อมูลโบนัสพิเศษ!

อีกหนึ่งสคริปต์ ทั้งหมดนี้ใช้เพื่อยกเลิกการต่อเชื่อมอุปกรณ์และลบไดเรกทอรีเมานต์ ก็ถือว่ามันมี privs sudoการทำเช่นนี้เพื่อให้คุณจะต้องทำงานด้วย ตอนนี้สคริปต์นี้ใช้จุดเมานท์แบบเต็มบน commandline เช่น:

$ /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

3
คุณยอดเยี่ยม! :)
kolypto

1
ถ้าฉันใช้ auto-mount.sh ด้วยตนเองมันใช้งานได้ แต่ไม่ใช่ถ้าฉันเสียบในไดรฟ์และไม่บูต : /
endolith

ดังนั้นปัญหาอยู่กับกฎ UDEV lemme ขยายส่วนนั้นเล็กน้อยเพื่อช่วยให้คุณแก้ปัญหาได้
ต้มตุ๋น Quixote

3
ฉันได้รวบรวมสคริปต์ทั้งหมดบน github: github.com/fatso83/Code-Snippets/tree/master/system-utils/ ...... พวกเขาทำงานได้ดีบน Ubuntu 10.10 และยังรวมถึงการยกเลิกการเชื่อมต่ออัตโนมัติ
oligofren

1
การอ้างอิง: udev_237 - man udev (Ubuntu_18.04) โปรดทราบว่าการเรียกใช้โปรแกรมที่เข้าถึงเครือข่ายหรือระบบไฟล์เมานต์ / unmount ไม่ได้รับอนุญาตภายในกฎของ udevเนื่องจากแซนด์บ็อกซ์เริ่มต้นที่บังคับใช้กับ systemd-udevd.service แหล่งที่มา: unix.stackexchange.com/questions/200194/…สำหรับวิธีการแก้ปัญหาให้ดูที่serverfault.com/questions/766506/…
สำรองข้อมูล Pro

9

ตัวเลือกสุดท้ายอย่างหนึ่งที่คนอื่น ๆ แนะนำไว้ในเน็ตคือivmanแต่ดูเหมือนว่าขึ้นอยู่กับpmountว่าคุณได้ระบุไว้แล้วไม่ทำงาน pmountถูกทอดทิ้งและivmanเกือบจะเหมือนกัน

สิ่งทดแทนivmanคือhalevtและมีให้ใน Karmic เป็นการปรับใช้ใหม่ivman(อ่าน: "บำรุงรักษา" และ "ไม่ได้ขึ้นอยู่กับจำนวนเงิน") แพคเกจไม่พร้อมใช้งานบน Jaunty แม้ว่าคุณจะสามารถสร้างมันเองได้หากคุณไม่ได้วางแผนที่จะอัพเกรด

เครื่องมือทั้งสองนี้อยู่เหนือเลเยอร์ DBus และ HAL และตอบสนองต่อเหตุการณ์จากพวกเขา เห็นได้ชัดว่าทั้งสองสามารถเรียกใช้เป็น daemon ของระบบหรือเป็นตัวจัดการเมาท์เซสชันผู้ใช้ (a la Gnome-VFS) - /etc/defaults/{ivman,halevt}ไฟล์มีค่าใช้จ่ายในการตั้งค่าระบบ

นี่คือคำแนะนำสำหรับการปรับแต่งivmanเพื่อใช้/media/<LABEL>จุดเมานท์ เป็นไปhalevtได้ว่ามีวิธีที่ง่ายกว่าในการทำ แต่บางทีพวกเขาอาจช่วยคุณค้นหาคำตอบได้


ทำงานกับ HALEVT

ปรับปรุง : ในความสนใจของการเมาท์ซีดี automagical เช่นกันซึ่งคำตอบ udev halevtของฉันไม่ได้ให้ผมมองลึกลงไปใน ฉันพบโพสต์บล็อกนี้ซึ่งช่วยอธิบายมากเกี่ยวกับกระบวนการ ฉันต้องคอมไพล์halevtแพ็กเกจของฉันเองสำหรับ Debian Lenny (โชคดีที่การอ้างอิงทั้งหมดอยู่ในส่วนของ lenny-backport) เมื่อติดตั้งแล้วกระบวนการส่วนใหญ่จะไม่น่ากลัว:

  1. ตรวจสอบให้แน่ใจว่าเปิดใช้งานระบบ halevt-daemon แล้ว /etc/default/halevt
  2. อนุญาตให้ผู้ใช้ระบบหยุดทำงานเพื่อเชื่อมต่ออุปกรณ์ใน/etc/PolicyKit/PolicyKit.conf(ดูด้านล่างแหล่งที่มา )
  3. ปรับเปลี่ยนนโยบาย HAL เพื่อคัดลอกป้ายกำกับปริมาณลงในจุดเมานท์ที่ต้องการใน/etc/hal/fdi/policy/preferences.fdi(ดูด้านล่าง)
  4. หากคุณต้องการการสนับสนุนแผ่น CD / DVD คว้าeject.halสคริปต์/usr/local/binจากบล็อกโพสต์ดังกล่าวข้างต้นแก้ไขและบันทึกใน
  5. แก้ไขการกำหนดค่าระบบ halevt เพื่อเปิดใช้งานการเมาท์ /etc/halevt/halevt.xml
  6. เพิ่มรหัสลงในสคริปต์ก่อนและหลังเซสชันของผู้จัดการเข้าสู่ระบบเพื่อหยุดระบบ halevt-daemon เมื่อมีคนเข้าสู่ระบบและรีสตาร์ทเมื่อพวกเขาออกจากระบบ

หากคุณต้องการรีสตาร์ท HAL และ HALEVT daemons เพื่อตรวจสอบการกำหนดค่าใหม่ของคุณให้ใช้สิ่งนี้เพื่อให้ได้ลำดับที่ถูกต้อง:

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 ตัวอย่างที่ดีเพื่อดู tweaks ของคุณเอง ส่วนใหญ่เกี่ยวกับการตั้งค่าการแทนที่แบบ gnome-mount สำหรับfluxboxสภาพแวดล้อมของผู้เขียนดังนั้นตัวอย่าง XML ของเขาจึงทำมากกว่าที่คุณต้องการ แต่มันเป็นวิธีที่ดีในการทำความเข้าใจกับสิ่งที่คุณสามารถทำได้ /usr/share/doc/halevt/examplesนอกจากนี้ยังมีตัวอย่างที่ดีใน

ฉันต้องวิ่งsudo sh -c "mkdir /var/halevt ; chown halevt:plugdev /var/halevt"ก่อนทุกอย่างจะทำงาน

นี่คือส่วนเพิ่มเติมของฉันเพื่อให้การทำงานอัตโนมัติซีดี / ดีวีดี:

<!-- CD/DVD mount -->
<halevt:Device match="hal.block.device &amp; hal.block.is_volume = true  &amp; hal.volume.is_disc = true &amp; 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

3
สำหรับคนที่อ่านบทความนี้ในปี 2556 พวกเขาควรรู้ว่า HAL ได้เลิกใช้แล้วและพวกเขาควรหันไปใช้โซลูชั่นที่ใช้พื้นฐานของ evev เช่นหนึ่งใน quack quixote ที่ได้รับมาข้างต้น
oligofren

6

เมื่อเวลาผ่านไปการแก้ปัญหาที่ง่ายขึ้นจะปรากฏขึ้น

โซลูชันนี้อาศัยแพคเกจซอฟต์แวร์ udevil ซึ่งเขียนขึ้นเพื่อจุดประสงค์นี้และไม่จำเป็นต้องแก้ไขกฎ udev มันอาจจะเป็นที่นิยม (สำหรับผู้ใช้ใหม่และเก่า) เป็นโซลูชั่นตรงไปข้างหน้า

devmonสคริปต์จาก udevil ไม่มายากลทั้งหมดในขณะที่เพียงขึ้นอยู่กับ udev และกะล่อน ทำงานเกือบจะออกนอกกรอบโดยไม่ต้องกำหนดค่าเริ่มต้น

สิ่งที่ฉันทำในเวิร์กสเตชันของฉันคือโทรหา devmon จากrc.localสิ่งนี้:
devmon 2>&1 >> /var/log/devmon &
เพื่อความสะดวกสบายของคุณคุณอาจต้องการฝังมันลงในสคริปต์เริ่มต้นแทนที่จะrc.localใช้เครื่องมืออัตโนมัติเช่นpleaserunสร้างมันขึ้นมา: https://unix.stackexchange.com/ A / 124609/42673

หลังจากที่มีมันทำงาน, การจัดเก็บข้อมูลที่ผมเสียบมีการตรวจสอบ (มันจะมองหาพาร์ทิชันและถ้ารูปลักษณ์พบได้ที่ป้ายระบบแฟ้มของพวกเขา) /media/FILESYSTEM_LABELแล้วติดตั้งเข้าไป
ไม่สามารถจินตนาการอะไรได้ง่ายไปกว่านั้นยกเว้นบางที systemd ที่มีชื่อเสียง (ใน) จะรวมฟังก์ชั่นนี้ในบางจุดในอนาคต

udevil อย่างรวดเร็ว ( github.io/udevil )
สคริปต์: devmon ( igurublog / script-devmon )


3

คำตอบของ quack quixote ไม่ทำงานบน 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

1
ขอบคุณ .. นี่เป็นวิธีที่ง่ายที่สุดสำหรับสิ่งที่ฉันต้องการสำเร็จ แม้ทำงานบน Ubuntu Server 16 ที่มีปริมาณ ntfs
ChrisPrime

3

สำหรับระบบที่ใช้ Debian (เช่น Ubuntu ฯลฯ ) มีแพ็คเกจusbmountที่เมาท์ไดรฟ์ USB ให้คุณโดยอัตโนมัติ โดยทั่วไปจะใช้วิธีการตาม udev ตามที่ระบุไว้แล้ว - เพียงแค่เป็นแพคเกจติดตั้งง่าย ดูเหมือนว่าผู้เขียนดั้งเดิมของแพคเกจจะหมดลง แต่อูบุนตู / เดเบียนยังคงดูเหมือนจะรักษามัน (ฉันเดาว่ามันไม่ซับซ้อน) - ดังนั้นจึงยังคงมีอยู่ในรุ่นล่าสุด

สคริปต์ที่ติดตั้งสามารถกำหนดค่า (/etc/usbmount/usbmount.conf) เพื่อให้จุดเชื่อมต่อที่เหมาะสม


1
Usbmount ไม่สามารถเมาต์ด้วยเลเบลได้เว้นแต่ว่าคุณจะเติมรายการของเลเบลในไฟล์คอนฟิกูเรชัน
Gilles

1
ดูโพสต์esite.ch/2014/04/11/…หากคุณต้องการเพิ่มการติดตั้งที่ฉลากเพื่อ usbmount โดยไม่ต้องบำรุงรักษารายการ
Oliver Sauder

3

เพื่อล้างคำแนะนำที่ดีเยี่ยมของ quack quixote ในการกำจัด:

เพิ่มบรรทัดต่อไปนี้ในไฟล์กฎ udev ที่คุณทำไว้ก่อนหน้า (/etc/udev/rules.d) "

ENV{ID_FS_LABEL_ENC}=="?*",   ACTION=="remove",      SUBSYSTEMS=="usb", \
         RUN+="/usr/local/sbin/udev-autounmounter.sh %k"

ถัดไปสร้างสคริปต์ต่อไปนี้และ chmod มันปฏิบัติ (/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} &

ในที่สุดสคริปต์ unmount เอง (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


ฉันคิดว่าif [ -n "$device_is_mounted" ]; thenควรจะเป็นif [ -z "${MOUNTPT}" ]; thenใช่มั้ย
eresonance

2

คุณอาจต้องการลอง Pysdm


นั่นเป็นเพียงตัวแก้ไข fstab อื่นใช่ไหม
endolith

ใช่ แต่ "นอกจากนี้ยังอนุญาตให้สร้างกฎ udev สำหรับการกำหนดค่าแบบไดนามิกของอุปกรณ์จัดเก็บข้อมูล"
Sathyajith Bhat

"การสร้างกฎ udev" จะช่วยฉันได้ไหม? ฉันไม่รู้ว่ามันหมายถึงอะไร มันติดตั้งอุปกรณ์แบบถอดได้ที่ไม่รู้จักก่อนหน้านี้โดยที่ผู้ใช้ไม่ได้เข้าสู่ระบบในเครื่อง
endolith

ขออภัยฉันไม่ได้เบาะแสใด ๆ กับกฎของ udev คุณสามารถดูได้ที่fredericiana.com/2006/03/15/writing-udev-rules-short-notesและreactivated.net/writing_udev_rules.html
Sathyajith Bhat

2

คุณสามารถลองใส่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แพ็คเกจซึ่งทำในสิ่งที่คุณต้องการ แต่อาจรบกวนการทำงานอัตโนมัติแบบปกติ


คำสั่งที่ไม่รู้จัก“ gnome-volume-manager” ฉันอยู่ใน Ubuntu Jaunty
endolith

มี / usr / lib / gnome-volume-manager / gnome-volume-manager แต่มันไม่ทำอะไรเลย
endolith

อ้อเข้าใจแล้ว. มีแพ็คเกจที่เรียกว่า gnome-volume-manager ด้วย ที่เกี่ยวข้อง: crunchbanglinux.org/forums/topic/239/…
endolith

ดูเหมือนว่า gnome-volume-manager จะใช้ HAL เพื่อต่อเชื่อมหรือไม่ และ "ในปี 2009 HAL กำลังอยู่ระหว่างการคัดค้าน DeviceKit" ทำไมทุกอย่างในลีนุกซ์จึงเป็นเช่นนี้? พวกเขาเริ่มที่จะทำให้บางสิ่งบางอย่างทำงานได้อย่างถูกต้องจากนั้นพวกเขาก็เอามันออกไปและแทนที่มันด้วยสิ่งใหม่ที่ไม่ทำงาน
endolith

pmount ไม่ทำงานอีกต่อไป > pmount / dev / disk / by-label / STORAGE ข้อผิดพลาด: อุปกรณ์ / dev / sdc1 ไม่สามารถถอดออกได้ togaware.com/linux/survivor/Using_Gnome_Volume_Manager.html
endolith

2

ภาคผนวกที่แก้ไขของฉันสำหรับวิธีแก้ปัญหา udev ที่ใช้ quack ของ quixote ถูกปฏิเสธดังนั้นฉันจะเอามันมาที่นี่ โปรดอ้างอิงโพสต์ของเขาก่อน

ครั้งแรกของทั้งหมดถ้าคุณต้องการให้กฎ udev ของคุณที่จะทำหน้าที่เมื่อใดอุปกรณ์ติดผ่านทางระบบย่อย SCSI (ซึ่งรวมทั้ง USB, FireWire และ eSATA) เปลี่ยนการแข่งขันในระบบย่อยกฎ udev SUBSYSTEMS=="scsi"ไป

อย่างไรก็ตามอย่าลืมว่าสิ่งนี้จะติดตั้งอะไรก็ได้โดยอัตโนมัติรวมถึงไดรฟ์ภายในหากคุณเสียบปลั๊กไว้ในขณะที่ระบบกำลังทำงานดังนั้นมันอาจไม่ใช่สิ่งที่คุณต้องการ

ประการที่สองนี่คือสคริปต์ที่ฉันใช้ซึ่งจะแทนที่สคริปต์ทั้งหมดในโพสต์นั้น นอกจากนี้ยังทำความสะอาดจุดยึดที่สร้างขึ้นโดยอัตโนมัติใน / สื่อ / ทันทีที่อุปกรณ์บล็อกติดตั้งถูกลบออก - ไม่จำเป็นต้องแทรกแซงด้วยตนเอง เพิ่มเติมแทนที่จะเรียกสคริปต์อื่นให้ทำงานในพื้นหลังมันทำให้ตัวเองในพื้นหลังเมื่อไม่ได้ดำเนินการจาก terminal (เช่นเมื่อดำเนินการผ่าน udev)

มันใช้ inotifywait เพื่อรอจนกระทั่งอุปกรณ์ที่เมาท์หายไปจากนั้นลบไดเรกทอรีที่สร้างขึ้น ดังนั้นคุณต้องติดตั้ง inotify-tools ไว้ในระบบของคุณ บน Distros ที่ใช้ 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>คำสั่งได้อย่างง่ายดาย แก้ไขให้เหมาะกับความต้องการของคุณ :)


คุณรันสคริปต์นี้อย่างไร halevtดูเหมือนจะไม่เป็นapt-getแพคเกจที่มีความสามารถในปัจจุบันสำหรับรุ่นที่ทันสมัย
Campbeln

Agh ... บางทีถ้าผมทำตาม TOP / รายการตอบรับจากนักต้มตุ๋นดอนกิโฆเต้ ... จะยังคงมีความสุขที่จะมีคำตอบที่ฟูลเลอร์ที่นี่ :)
Campbeln

1

ลองกำหนดค่าผ่านตัวจัดการเพื่อให้คุณไม่ต้องป้อนข้อมูลด้วยตนเอง

มันควรเป็นส่วนหนึ่งของที่เก็บอูบุนตู


คุณจะต้องเปิดใช้งานส่วนจักรวาลเพื่อรับมัน
ต้มตุ๋น Quixote

apt: mountmanager? section = universe;)
endolith

นั่นเป็นเพียงการตั้งค่า fstab สำหรับฉันหรือไม่
endolith

@endolith: จะไม่ฉลาด: จักรวาล? install = mountmanager มีเหตุผลมากขึ้นหรือไม่ ;)
Bobby

รูปแบบดังกล่าวใช้งานได้หรือไม่ มันไม่ได้พูดอย่างนั้นใน man page manpages.ubuntu.com/manpages/karmic/en/man8/apturl.8.html
endolith

-5

หากคุณมีไดรฟ์หนึ่งตัวต่อครั้งคุณสามารถแก้ไขไฟล์นี้ใน/etc/fstabไฟล์ของคุณได้ บางสิ่งบางอย่างตาม:

/dev/sdb1     /mnt/usbdrive     ext3     defaults 0   0

สิ่งนี้ควรติดตั้งตอนบูตและทำให้ทุกคนสามารถเข้าถึงได้ด้วยการใช้ perms หากคุณมีไดรฟ์มากกว่าหนึ่งตัวคุณยังสามารถทำได้ด้วย:

/dev/sdb1     /mnt/usbdrive1     ext3     defaults 0   0
/dev/sdc1     /mnt/usbdrive2     ext3     defaults 0   0

6
ชัดเจนไม่ใช่คำถามที่ถาม
ต้มตุ๋น Quixote
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.