在没有任何桌面环境的情况下,如何在/ media / <LABEL>中自动安装可移动媒体?


17

我有一个Debian sid系统(Wheezy)(与arch同样),没有任何桌面环境(也没有Xorg)。

我可以/media/使用mount/ 手动将我的SD卡,USB记忆棒,外部HDD通过标签安装到指定目录中,umount并在中将适当的条目安装/etc/fstab到引导中,或者在引导时自动将其安装到指定目录中,但这很引人注目,但对于我的需求而言,限制性和动态性不足:如果我希望将它们安装在中/media/<LABEL>,则每个不同的设备都<LABEL>需要有自己的条目,并且每个<LABEL>子目录也需要手动创建/删除/media/)。

那么,什么是安装它们的最好方式自动/media/<LABEL> 在插入(并尽快从文件系统中卸载它们,因为它们已被拔掉,不管它是如何将数据风险)?

理想的解决方案是:

  1. 当可移动介质被插入的检测(即,当在加入/dev/sdaxsdbx,...通过udev
  2. /media/根据其标签(可移动媒体的标签)创建目录
  3. 在目录挂载/media/<LABEL>RW模式(如果它的文件系统支持的是)与flush选项(一vfat
  4. 检测媒体是否已拔出
  5. 如果是这样,请从文件系统中卸载它
  6. 从中删除相应的目录 /media/

(该设备应安装在同步模式oviously,以避免任何数据丢失时热拔,因为缓存的编辑 sync太多的vfat可移动媒体这样flush 已创建了妥协,不太安全比sync照命,但风险较小周期的闪存)

我发现的一些信息autofsHALudisksudisks2usbmount等,但目前还不清楚哪一个是过时或首选,反正我还没有想出如何将它们轻松地在我的系统做的配置,到现在为止...


首先,您是否搜索过类似的问题?我记得已经有人问过了。其次,卸载应在拔出之前进行。
enzotib 2012年

1
当然,我做了:o]在这里以及在超级用户上。问题在于工具会不断发展(udisks / udev),或者已被弃用(HAL?),其他“不受欢迎的”工具(udisks2?)等等。无论如何,我一直找不到任何可行的解决方案。我发现要了解的大多数内容都依赖于桌面环境机制(Gnome,KDE或XFCE)。我不想安装任何东西。关于取消静音,不一定。如果设备设置为sync,则恶魔可以在检测到已拔出设备且没有数据丢失的情况下从fs卸载设备。所有台式机发行版都可以这样做。我想要在终端。
cedbeu 2012年

看看这个替代品halevt。关于卸载,通常DE希望您在物理上拔出设备之前从文件管理器中退出该设备。
enzotib 2012年

没错。但是我已经看到,某些(以前使用过的)守护进程可以从fs卸载设备,这些设备在拔出之前尚未卸载,甚至会自动从/ ​​media /中删除其对应的目录,并且保持正常的工作方式(如果设备配置为当然是同步的)。感谢您的链接。我一回到udisksevt就可以看看。我已经看过devmon和udiskie了,但是它们不在Debian软件包中。如果我能找到其他东西,我会尝试的,但是我不相信Debian上没有本机解决方案。
cedbeu 2012年

1
我在Debian也和我用fdisk -l,然后mount-这两个命令,但是OK,如果你想让它自动化的,你必须解析fdisk -l输出,然后把它放在mount-我做这样的东西有headtailtrcut,等等,但是专业人士通常会这样做awk,甚至更好的是,在正确的位置查找数据。关于删除,至少对于我来说,当我挂载到时/mnt,这是自动完成的。关于扳机(插入电源时)我不知道,但是请告诉我们解决办法。
伊曼纽尔·伯格

Answers:


10

我认为您正在寻找pmount

如果要在插入时自动安装,请参阅在Debian上自动安装USB记忆棒

如果您的系统使用udisks2,那么这是对插入可移动存储设备做出反应的首选方式。有关Udisk的配置提示,请参见Arch Wiki

否则,出现新设备时会做出反应的程序是udev,因此自动挂载由udev规则触发。该usbmount包提供udev规则来自动挂载USB存储设备和其他几个人。mount从udev规则调用不适用于FUSE文件系统(例如ntfs-3g),因此如果需要,请使用udisk。

删除介质后,您将无法自动卸载它们,因为因果关系无法正常工作。在卸下介质之前,必须先将其卸下。对于只读媒体,您可以免除删除后的卸载,尽管如果某些应用程序在突然消失的文件系统上打开了文件,这可能会使它们感到困惑。对于可写媒体,如果拔出已挂载的文件系统,则可能会损坏数据。


感谢一百万的答案。我会尽快尝试,并让这里的人知道。关于取消通话。伙计们,请不要再告诉我这不是因果关系的问题::o在将设备配置为同步后,完全拔掉设备的电源是完全可行的(并且有可能)。然后,这是文件系统的问题。如果已传输数据而未进行缓存(同步),则无需卸载就可以拔出插头。然后,可以执行卸载,并且在通知系统该设备不再存在时有用。
cedbeu 2012年

1
@cblab您过于简单了。如果打开了一个文件以进行写入,然后将设备拉出,则该文件很可能已损坏。卸载可确保没有打开任何文件。在许多文件系统(虽然不是FAT)上,卸载不仅仅是将脏位设置为0,它们需要例如刷新日志。对于闪存设备,同步安装的一个主要问题是它会很快磨损设备,因为这会阻止写入分组。参见superuser.com/questions/180722/…readlist.com/lists/vger.kernel.org/linux-kernel/22/111748.html
别再作恶了'

嗨@吉尔斯(Gilles)。多谢您的回覆。不过,我认为我并不过分。您在某些方面是正确的。但是,用户可以决定是否要冒险。您会同意的,您的帖子已有7年历史了;现在,flush专门为vfat这些应用程序设计的安装选项可以避免这些问题:在每个块之后都不会执行写入操作,而是在设备似乎不活动时立即执行写入操作。闪存也极大地延长了其死胡同的生命周期。现在,很明显,用户必须知道在打开文件时或在复制过程中(或之后)不要拔出设备。但这是一个很好的妥协。
cedbeu 2012年

无论如何,usbmount对我来说可能是个不错的选择,但不幸的是,它不会根据设备的标签名称将其安装在文件夹中,但是在中/media/usb-*,它不符合我的需求。我希望能够在检测到设备时/media/<DEV_LABEL>通过flush参数自动挂载设备(如果可能,可通过动态创建目录),并/media/在不再检测到它们时自动卸载它们并从中删除目录。我要承担的风险由我自己决定。
cedbeu 2012年

1
请注意,usbmount此后jessie不再支持NTFS :bugs.debian.org/774149
malat 2015年

2

这是我最近的操作方式,现在我对这种方法感到非常满意。这是针对Ubuntu 12.04 + gentoo的,但是我想任何发行版都可以安装udev和autofs。

先决条件:您必须已安装udev + autofs。

步骤1)

创建以下“ /etc/udev/rules.d/90-usbsd-auto.rules”文件(当然,您可以使用任何以“ .rules”结尾的名称)。:

# Add symlink /dev/usbdisks/<label> to /dev/sd[a-z][1-9] 
# if partition has a label
# Add symlink /media/usb/<label> to /media/autousb/<label>
# for automounter support
ACTION=="add", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}=="?*", \
    SYMLINK+="usbdisks/$env{ID_FS_LABEL_ENC}", MODE:="0660", \
    RUN+="/bin/rm /media/usb/$env{ID_FS_LABEL_ENC}", \
    RUN+="/bin/ln -sf /media/autousb/$env{ID_FS_LABEL_ENC} /media/usb/$env{ID_FS_LABEL_ENC}"

# Fallback: If partition has a NO label, use kernel name (sd[a-z][1-9])
ACTION=="add", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}!="?*", \
    SYMLINK+="usbdisks/%k", MODE:="0660", \
    RUN+="/bin/rm /media/usb/%k", \
    RUN+="/bin/ln -sf /media/autousb/%k /media/usb/%k"

# Some FileSystems emit a "change" event when they are unmounted.
# UDEV seems to delete the device symlink in this case :-(
# So we need to re-create it here
ACTION=="change", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}=="?*", \
    SYMLINK+="usbdisks/$env{ID_FS_LABEL_ENC}", MODE:="0660"

# Fallback: If partition has NO label, use kernel name
ACTION=="change", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}!="?*", \
    SYMLINK+="usbdisks/%k", MODE:="0660"


# When device is removed, also remove /media/usb/<label>
ACTION=="remove", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}=="?*", \
    RUN+="/bin/rm /media/usb/$env{ID_FS_LABEL_ENC}"

# Fallback: If partition has no label, remove /media/usb/%k
ACTION=="remove", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", ENV{ID_FS_LABEL_ENC}!="?*", \
    RUN+="/bin/rm /media/usb/%k"

这是做什么的:它创建两个符号链接,一个符号链接用于“ / dev / usbdisks / <...>”下的USB存储设备分区。如果没有标签,它将使用USB存储分区的标签或内核名称。第二个符号链接将从“ / media / usb / <...>”链接到“ / media / autousb / <...>”,以实现自动安装程序支持(请参阅步骤2)。

注意:我最初不将规则与ID_FS_LABEL_ENC变量一起使用,因为我认为这很危险。如果插入两个使用相同标签的USB记忆棒会怎样?

但是发帖人特别想使用USB磁盘的标签,因此我相应地修改了规则。

为了确保udev读取这些规则,请使用

sudo udevadm control --reload-rules

使用此udev规则文件,所有内容都已设置为自动挂载USB存储设备分区。请注意,虽然现在不会自动安装设备(有意)。一旦与

第2步)

设置autofs以自动挂载/ media / autousb / <...>:我在“ /etc/auto.master”文件中添加了以下行(对于Ubuntu 12.04):

/media/autousb /etc/auto.usb --timeout=60

这意味着60秒钟不活动后,AutoFS将卸载设备。您可能要根据自己的口味少用或多用。

对于Gentoo,您必须修改“ /etc/autofs/auto.master”,因此使用起来很有意义

/media/autousb /etc/autofs/auto.usb --timeout=60

现在,我创建了具有以下内容的“ auto.usb”:

#!/bin/bash

key=${1}
fstype=$(/sbin/blkid -o value -s TYPE /dev/usbdisks/${key})
if [ "${fstype}" = "vfat" ] ; then
  echo "-fstype=vfat,sync,uid=0,gid=plugdev,umask=007 :/dev/usbdisks/${key}"
  exit 0
fi
if [ "${fstype}" = "ntfs" ] ; then
  echo "-fstype=fuse.ntfs-3g,sync,uid=0,gid=plugdev,umask=007 :/dev/usbdisks/${key}"
  exit 0
fi
if [ "${fstype}" = "ext4" ] ; then
  echo "-fstype=ext4,sync,nocheck :/dev/usbdisks/${key}"
  exit 0
fi

exit 1

该auto.usb必须是可执行的,以便autofs将此用作(bash)脚本。所以举个例子

sudo chmod 0755 /etc/auto.usb

这是做什么的:该脚本将告诉AutoFS(/ usr / sbin / automount)如何挂载USB存储设备分区。

该脚本将首先使用“ / sbin / blkid”来查找分区上的文件系统类型。

然后,脚本将根据设备分区提供正确的安装选项。

注意:我提供了“ vfat”(可能是USB记忆棒最常见),“ ntfs”和“ xfs”文件系统的示例代码。当然,扩展它以支持更多文件系统是很容易的。

步骤3)可选...要“弹出” ==卸载USB存储棒(或USB存储棒上的分区),请在/ sbin / usbeject下创建一个脚本:

#!/bin/bash
killall -s SIGUSR1 /usr/sbin/automount

使用此脚本,您可以使用“ sudo usbeject”来卸载所有已安装的USB设备分区(通过告诉automount卸载它们)。

当然,您可以简单地确保该分区没有在任何地方使用。60秒超时后,自动挂载程序将卸载该分区...

真正的诀窍是使用从“ / media / usb”到“ / media / autousb”的符号链接:

  • “ / media / usb”符号链接将由udev创建,为用户提供了一个简单的概览,其中列出了哪些USB存储设备分区
  • 如果通过/ media / usb使用分区,则AutoFS将根据需要自动挂载该分区
  • 使用脚本化的“ auto.usb”文件,您可以支持任何类型的文件系统,此外,您还可以支持任何种类的命名方案。
  • 即使这些分区使用不同的文件系统类型,此方法也支持具有多个分区的USB记忆棒。

2

好的,已经有很长的时间了,但是我仍然会用到目前为止找到的最佳选择来回答我的问题。总结一下:创建一条udev规则,该规则与某些脚本关联(将创建/删除目录并卸载/挂载可移动设备),并附加到udev设备事件type =上partition

1-创建添加/删除脚本

将以下脚本保存storage-automount.sh/lib/udev/并使其可执行(sudo chmod a+x /lib/udev/storage-automount.sh):

#!/bin/sh

# set the mountpoint name according to partition or device name
mount_point=$ID_FS_LABEL
if [ -z $mount_point ]; then
    mount_point=${DEVNAME##*/}
fi

# if a plugdev group exist, retrieve it's gid set & it as owner of mountpoint
plugdev_gid="$(grep plugdev /etc/group|cut -f3 -d:)"
if [ -z $plugdev_gid ]; then
    gid=''
else
    chown root:plugdev $mount_point
    gid=",gid=$plugdev_gid"
fi

# create the mountpoint directory in /media/ (if not empty)
if [ -n $mount_point ]; then
    mkdir -p /media/$mount_point
    # other options (breaks POSIX): noatime,nodiratime,nosuid,nodev
    mount -t $ID_FS_TYPE \
      -o rw,flush,user,uid=0$gid,umask=002,dmask=002,fmask=002 \
      $DEVNAME /media/$mount_point
fi

将以下脚本保存storage-autounmount.sh/lib/udev/并使其可执行(sudo chmod a+x /lib/udev/storage-autounmount.sh):

#!/bin/sh

# set the mountpoint name according to partition or device name
mount_point=$ID_FS_LABEL
if [ -z $mount_point ]; then
    mount_point=${DEVNAME##*/}
fi

# remove the mountpoint directory from /media/ (if not empty)
if [ -n $mount_point ]; then
    umount -l /media/$mount_point
    rm -R /media/$mount_point
fi

2-创建udev将这些脚本附加到事件的规则

最后,在中添加一条udev规则/etc/udev/rules.d/,例如85-storage-automount.rules

ENV{DEVTYPE}=="partition", RUN+="/lib/udev/storage-automount.sh", ENV{REMOVE_CMD}="/lib/udev/storage-autounmount.sh"

并使其具有与该目录/文件夹中其他规则相同的权限

现在,当您插入存储设备时,将/media/根据分区名称创建一个目录(我不记得了,但我认为它也适用于NTFS分区),并且您的分区将被挂载到该目录中。如果您plugdev的系统上有一个组,则对用户是R / W。此外,设备以同步模式安装,以限制在热拔插情况下数据丢失的风险。

删除设备后,将卸载设备并从中删除目录 /media

另外,用于监视udev事件的工具是udevadm monitor,具有类似--env或的选项--property

$ udevadm monitor --env

经过测试,它在debian和arch上都可以正常工作,但可能在所有依赖的发行版上都可以工作udev


我认为+ r应该在“将其设置为可执行文件(sudo chmod + r /lib/udev/storage-autounmount.sh)”中用+ x代替
杰里米

我有一个新的jessie安装程序,在该安装程序上我严格按照您的指示进行操作,但是即使重启后也无法从tty1中进行自动挂载(这不在您的说明中,但我也没有在重新启动前进行自动挂载)。检测到插入USB驱动器(我收到控制台消息),但是/ media /中什么都看不到(cdrom除外)。我可以手动安装USB驱动器,所以我也知道它也可以工作。[继续以下评论]
TomRoche

[从先前的评论继续]我已经安装了package = udev,预先填充了dirs = {/ etc / udev / rules.d /,/ lib / udev /},并且在$ PATH中具有了可执行文件= udevadm。我想知道(1)您在哪个Debian版本中进行了这项工作?(我假设是发狂的)(2)您还安装了哪些Debian软件包udev
TomRoche

@TomRoche当时是Wheezy,的确没有安装任何特殊的软件包,我试图做一个简约的安装,并且试图避免使用最小安装所没有提供的软件包。我不需要重新启动,这就是为什么这不在我的说明中。很长一段时间以来,我还没有深入研究……我可能会很快再试一次。
cedbeu

1

我认为已经很晚了,但是如果有人需要,我会发布它:(也是我的第一个StackExchange答案)

在许多地方检查了解决方案之后,我在Arch Wiki中找到了一个简单的解决方案:

链接到Arch Wiki

我们可以添加udisks2规则将默认安装目录从更改/run/media/$USER//media/<Label>

/etc/udev/rules.d/名称中添加以下规则,例如99-udisks2.rules

ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{UDISKS_FILESYSTEM_SHARED}="1"

然后,我们可以安装一个简单的工具,例如Udiskie进行自动挂载。


嗨,欢迎来到这里。感谢您的选择。对于Udiskie,我实际上想要一个完整的命令行选项(系统上没有Xorg或任何图形界面)。并且…问题已经有6.5年的历史了(哇,天哪!),我想事情现在已经改变了:)但是无论如何,您的第一个答案+1,谢谢。
cedbeu

1

请参阅ArchWiki Udev页面。您不应mount从Udev规则或Udev规则执行的脚本执行。

但是,如udev-media-automount项目中所示,通过从Udev规则调用Systemd单元来执行此操作非常简单,该规则然后调用执行安装的脚本。与udisks2和其他解决方案不同,udev-media-automount适用于以下简单情况:您想以root用户身份挂载某些东西,而不必等待桌面环境或“用户会话”出现。这似乎恰恰是OP所要求的,我发现它既实用又易于理解。


好的谢谢。这是我问过的一个非常老的问题(将近7年前……并没有让我感到年轻^^)。但是,我将看看您的主张。从那时起,我认为系统化环境变得更加成熟。谢谢,我来看看!
cedbeu

0

我找到了一种方法,方法是编辑/ etc / fstab文件。一个简单的条目如下所示:

/dev/sdb1 /media/robot/hdd1 ntfs defaults 0 0

<file system> <mount point> <type> <options> <dump> <pass>


装入中/etc/fstab只会在引导时自动装入。
Graeme

@Graeme,我有一个通过/ etc / fstab挂载的sdcard。作为测试,我尝试从计算机上卸下并物理移除sdcard。我确认坐骑不再通过'df'显示。当我重新插入sdcard时,即使我没有明确地重新安装它,该挂载也会重新出现。这是在Ubuntu 16.04上。
吉诺(Gino)

@ Gino,Ubuntu已经默认完成自动挂载一段时间了。
Graeme

@Graeme,看来Ubuntu自动挂载程序正在/ etc / fstab中选择正确的挂载(如果存在)。因此,至少在Ubuntu 16.04上,该安装会在引导时以及在随后重新插入到usb端口(如果有)之后自动进行安装
Gino

@Gino我已经有一段时间没有使用Ubuntu了,但是我敢肯定,无论fstab中有什么,它都会自动挂载您的sd卡。与现代系统上的其他磁盘相比,Fstab更多地是关于设置核心系统元素。
Graeme
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.