挂载特定的闪存驱动器时如何运行脚本?


46

当安装了特定的USB设备时,是否可以运行脚本?

我将视频保存在单独的USB上,并希望运行一个脚本,将USB设备上的视频文件夹安装到主文件夹中的一个。

Answers:


31

现在,systemd有更好的解决方案。您创建的服务取决于您的媒体并需要它,例如:/etc/systemd/system/your.service

[Unit]
Description=My flashdrive script trigger
Requires=media-YourMediaLabel.mount
After=media-YourMediaLabel.mount

[Service]
ExecStart=/home/you/bin/triggerScript.sh

[Install]
WantedBy=media-YourMediaLabel.mount

然后,您必须启动/启用该服务:
sudo systemctl start your.service
sudo systemctl enable your.service

挂载后,systemd触发您的触发脚本。相对于udev规则的优势在于,脚本在挂载后真正启动,而不是在添加系统设备后启动。

用例:我有一个加密的分区,想要自动备份。添加设备后,我必须输入密码。如果我将备份脚本挂接到了udev,则该脚本会在我输入密码时尝试运行,这将失败。

资源:使用udev编写脚本

注意:您可以通过以下方式找到设备单元:systemctl list-units -t mount


我希望2016年4月即将到来。下一个Ubuntu LTS将启用systemd。AFAIK以上的好解决方案需要Ubuntu 15.04或更高版本。
guettli

哦,我认为systemd已经在ubuntu中。我实际上正在运行debian Stretch ;-)
2015年

@sumid如果我要将它放在〜/ .config / systemd下,它将起作用吗?
Khurshid Alam

4
大!在Debian Jessie中测试。不要忘记启用您的服务systemctl enable your.service。脚本文件必须是可执行的。
科尼

1
对我来说,这失败了。当我尝试启动该服务时,它抱怨“找不到unit media-bb.mount。”。我将拇指驱动器的(FAT32)FS称为“ bb”,以确保其中没有奇怪的字符,并且它不会太长或类似的内容。我尝试了Requires=和的After=,和WantedBy=media-bb.mountmedia-BB.mount因为Nautilus将音量显示为“ BB”,而不是“ bb”。相同的错误消息,除了大写。怎么了?我必须以某种方式创建该media-<something>.mount服务吗?
UTF-8

29

首先在中找到您的设备lsusb。记下ID(例如0a81:0101

/etc/udev/rules.d/via中创建一个新的udev规则文件,sudoedit /etc/udev/rules.d/100-mount-videos.rules并在其中按一个新规则:

ACTION=="add", ATTRS{idVendor}=="0a81", ATTRS{idProduct}=="0101", RUN+="/home/your_username/bin/mount_videos.sh"

请注意我如何使用中的ID lsusb

然后,您只需要编写脚本即可完成工作。一个简单的安装命令应该起作用。您可能需要sleep 5在其中使用命令来等待文件系统初始化(如果您离开gnome进行主挂载,但是您可以自由地先挂载它,然后可能不需要休眠)。

Allan的补充:长时间运行的脚本可能会阻止“此设备或从属设备的所有其他事件”。我的Mint手册页进一步指出:“长时间运行的任务需要立即与事件流程本身分离。” 没有提示在何处获得执行此操作的技巧。

来自Oli的回复:像这样包装:https : //askubuntu.com/a/106359/449


4
我可能建议在“ RUN”命令前加上“ su your_user -c”,以使脚本不会以root特权运行。
Kees Cook

3
@Kees因为这里的目标越来越高,但是保持root privs可能是一个好主意。也许将脚本保留在用户/root/只能在家的地方或只有root可以编辑的地方,而不是将其保留在用户的家中。
奥利

2
这不能回答问题。该问题询问在安装 USB驱动器时如何运行脚本。此答案说明了如何运行插入 USB驱动器的脚本。差异对我很重要,因为我有这样的脚本(用于数码相机)。如果没有脚本,则驱动器可能会或可能会在插入时挂载(取决于用户设置),并且只有在挂载驱动器时我才想做某事(复制映像)。因此,我的脚本(在添加驱动器时运行)通常在错误的时间运行。
Reinier Post


这是一种非常具体(脆弱)的实现方式。@sumid答案更适用于使用systemd的
MrMesees '16

8

获取ATTRS {idVendor}和ATTRS {idProduct}的值的另一种方法(在Ubuntu 12.04中测试):

  1. 找到您的USB挂载位置:

    $ mount | grep /dev/sd*
    

    这显示如下内容:

    /dev/sdb on /media/SOMEDIR type vfat ...
    
  2. 使用udevadm获取该设备信息:

    udevadm info -q all -n /dev/sdb | grep -E -i -w '.*VENDOR_ID.*|.*MODEL_ID.*'
    

    输出应该是这样的:

    E: ID_MODEL_ID=001a
    E: ID_VENDOR_ID=002b
    
  3. 现在,将型号ID用于ATTRS {idProduct},将供应商ID用于ATTRS {idVendor}

    ACTION=="add", ATTRS{idVendor}=="002b", ATTRS{idProduct}=="001a" ...
    

1

在Nautilus中的“编辑”>“首选项”>“媒体”下,您可以选择“其他操作”,而不是“ costum命令”。用于执行不同类型的媒体。到那时USB驱动器已经安装好了,但是我想您仍然可以(使用costum命令)将其链接到要在其中显示驱动器的文件夹。


司令部穿着服装吗?还是服装?
erjoalgo 2013年

1

如果您不想干扰文件管理器(nautilus,konquerer,gnome等)对安装和卸载设备的控制,建议不要使用udev路线。

相反,如果您的系统使用udisk ,请使用udisks-glue(几乎全部使用)。

安装后,只需~/.udisks-glue.conf在您的主目录中创建一个配置文件,如下所示。

以下示例在每次插入SD卡时都会更新相机上的GPS-Assist数据。

filter BT16EXTREME {
  optical = false
  partition_table = false
  usage = filesystem
  label = BT16EXTREME
}
match BT16EXTREME {
  post_mount_command = "/home/bernhard/update-gps-assist-data.pl %mount_point"
}

之后,只需确保在启动或登录时启动udisks-glue。即通过gnome的启动应用程序


1
不支持udev2 :-(
sumid 2015年


0

@sumid的答案有问题。你应该不会启动该服务。您只需要启用它。

文件: /etc/systemd/system/your.service

[Unit]
Description=My flashdrive script trigger
Requires=media-YourMediaLabel.mount
After=media-YourMediaLabel.mount

[Service]
ExecStart=/any_path_even_inside_the_mount_point/script.sh

[Install]
WantedBy=media-YourMediaLabel.mount

然后启用该服务:

sudo systemctl enable your.service

就这样。

注意:您可以通过以下方式找到您的中间标签:sudo systemctl list-units -t mount

注意2:如果服务由于某种原因失败(例如,脚本不可执行),则安装点将更改为<old_mount_point_name>1下次安装USB设备的时间。要解决此问题,您只需执行sudo systemctl reset-failed

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.