在pcmanfm中执行“弹出USB驱动器”操作

我想知道在Lubuntu中是否有一种方法可以创建自定义的pcmanfm操作来弹出USB驱动器?我尝试使用udisksctl来实现这个,但是--object-path选项给我报错了:
(udisksctl unmount:10926): GLib-GIO-CRITICAL **: g_dbus_object_manager_get_object: assertion 'g_variant_is_object_path (object_path)' failed
Error looking up object with path /media/user/Flash-Drive

而且简单文件夹和挂载驱动器之间没有MIME类型的区别,所以“弹出”操作会显示在所有文件夹上。

更新

嗯,看起来我找到了某种解决方案。这将卸载并关闭您的USB驱动器。

[Desktop Entry]
Type=Action
Tooltip=Eject selected flash drive
Name=Eject flash drive
Profiles=profile-zero;
Icon=media-eject

[X-Action-Profile profile-zero]
MimeTypes=inode/directory;
Exec=gksudo eject %f
Name=Default profile

此外,您可以在将setuid添加到/usr/bin/eject后,无需gksudo提示即可使用它。
[Desktop Entry]
Type=Action
Tooltip=Eject selected flash drive
Name=Eject flash drive
Profiles=profile-zero;
Icon=media-eject

[X-Action-Profile profile-zero]
MimeTypes=inode/directory;
Exec=eject %f
Name=Default profile

但是这个操作将在所有文件夹中显示。我仍然不知道如何区分USB驱动器目录和闪存驱动器目录。我看到了.desktop条目的规范Basenames,它指定了所选文件名(在清空回收站操作中使用),所以可能有一种方法可以指定文件放置位置吗?

更新2

好的,根据MIME-info数据库,我找到了适当的MIME类型- inode/mount-point,但现在操作根本不显示在任何目录中。可能是什么原因导致的问题?
[Desktop Entry]
Type=Action
Tooltip=Eject selected drive
Name=Eject drive
Profiles=profile-zero;
Icon=media-eject

[X-Action-Profile profile-zero]
MimeTypes=inode/mount-point
Exec=eject %f
Name=Default profile

确切的命令是什么? - Tim
udisksctl卸载 --object-path /media/user/Flash-Drive - Nicholas V.
没有名为/media/user/Flash-Drive的文件。 - Tim
这是我的USB驱动器自动挂载的位置。我想我只是不理解--object-path选项? - Nicholas V.
不,你的USB会挂载在/media/YOURUSERNAME/USBNAME。你需要用正确的名称替换userFlash-Drive - Tim
你创建了file.desktop这个文件吗?它的内容是什么? - kyodake
@kyodake 是的,但它不起作用,也没有什么特别的,只是尝试使用%f参数调用脚本。脚本使用udiskctl来卸载和关闭驱动器。问题是即使从命令行中,udisksctl对我也不起作用。另一个问题是桌面链接到USB驱动器的MIME类型是inode/directory。 - Nicholas V.
@NicholasV. 这与它需要一个对象而不是路径有关:http://askubuntu.com/questions/633037/what-is-an-object-path/633045#633045 - Tim
4个回答

我在这个问题上取得了更多进展,但解决方案仍然不理想:
我正在使用Lubuntu 16.04和PCManFM 1.24。对于USB闪存驱动器,我可以选择“弹出可移动介质”,但对于USB磁盘驱动器,我无法像在Nautilus中那样选择“安全移除驱动器”(我只能选择卸载)。
首先,问题是如何在设备上获得右键上下文菜单,在PCManFM的左窗格中,不幸的是,设备的操作似乎不受支持(或者在Nautilus中也是如此,但在Nemo中,左窗格中的操作是有效的,但在Nemo中,操作的实现方式有所不同)。 我有一个解决办法,通过在编辑-首选项-布局中勾选“显示位置”下的“设备”,在左窗格中显示“设备”图标,然后您可以在右窗格中右键单击设备,如附带链接所示: pcmanfm设备右键单击图像 第二个问题是安全移除驱动器的脚本: 在上面的示例中,传递给操作脚本的参数是: computer:///ST1000LM010-9YH146.drive(或者只是ST1000LM010-9YH146和%w) 这并不理想 - 我认为它不能完全唯一地标识驱动器,因为它不包括序列号。以下是“udisksctl status”的输出:
$ udisksctl status
MODEL                     REVISION  SERIAL               DEVICE
--------------------------------------------------------------------------
WDC WD5000BEVT-22ZAT0     01.01A01  WD-WX70A9903180      sda
Kingston DataTraveler G3  1.00      001CC0EC31D0F081F6071284 sdb
ST1000LM010-9YH146        CC9F      W2M076TD             sdc 

这样,我的脚本就能与模型匹配,因此假设您没有同时插入两个相同的设备来选择设备。 要实现脚本,请创建文件 ~/.local/share/filemanager/actions/eject.desktop
其中包含:

[Desktop Entry]
Type=Action
Name=Safely Remove Drive
Icon=drive-harddisk-usb
Profiles=profile-zero;

[X-Action-Profile profile-zero]
MimeTypes=inode/mount-point
Exec=/home/mike/.local/share/file-manager/actions/eject.sh %w 
Name=Default profile

我已经将脚本 eject.sh 放置在 ~/.local/share/filemanager/actions 中由 "Exec" 指定位置,但注意在桌面文件中无法使用 "~" 或 "$HOME",因此必须指定完整路径,就像我上面所做的那样。
脚本 eject.sh 应包含:
device=`udisksctl status | awk -v d=$1 '
BEGIN {
    gsub("%20"," ",d)
    sub("$"," ",d)  # Add a space on the end to give a more exact match
    sub("^","^",d) # Add ^ to start to give a more exact match
    }
$0 ~ d {
    print "/dev/"$NF
    }' `
if [ "$device" == "/dev" ]
then
    echo "Removable device not found"
else
    for dev in `df | awk -v device=$device '$1 ~ device {print $1}' `
    do
        echo "Unmounting "$dev
        udisksctl unmount -b $dev
    done

    echo "Powering off: "$device
    udisksctl power-off -b $device
fi

我的建议是使用umount命令。

通过fdisk -l命令和插入不同的USB驱动器来确定其识别为/dev/sdd1

在创建操作(file.desktop)之前,先创建它的目录:

mkdir -p ~/.local/share/file-manager/actions

使用以下终端命令逐个创建和编辑操作文件(umount.desktop):

touch ~/.local/share/file-manager/actions/umount.desktop
nano ~/.local/share/file-manager/actions/umount.desktop

将以下内容粘贴到umount.desktop中:
[Desktop Entry]
Type=Action
Name=Eject Usb-Drive
Icon=dialog-password
Profiles=profile-zero;

[X-Action-Profile profile-zero]
Exec=umount /dev/sdd1
Name=Default profile

这个答案确实使用了pcmanfm,但我发现它是最方便的一个。简而言之,在lxpanel中使用lxpanel添加一个图标到gnome-disks。

具体步骤如下:

在lxpanel上右键点击并选择“添加/删除面板项目”。添加一个新的“应用程序启动栏”,并将其放置在已经存在的“数字时钟”之前(或者附近)。在新添加的“应用程序启动栏”中,将“首选项/磁盘”设置为应用程序。这是Lubuntu自带的gnome-disks应用程序。

如果您需要对磁盘进行操作,只需在面板上点击磁盘图标。然后从顶部菜单中选择磁盘并选择“关机”。

这与Windows操作系统中的“安全移除硬件”功能相同,并且以上述方法将其放置在桌面上与Windows的位置几乎相同。


谢谢你!我一定会尝试使用你的解决方案。 - Nicholas V.
@ppp,谢谢,这真的很方便(对于这么晚才评论我很抱歉:)。唯一缺少的是为某些操作/磁盘分配快捷键的可能性 :) - A S

您的指令
udisksctl unmount --object-path /media/user/Flash-Drive

出错了。

/media/user/Flash-Drive 不是一个对象路径。


用以下命令找到对象路径: $ gdbus introspect --system --dest org.freedesktop.UDisks --object-path /org/freedesktop/UDisks/devices --recurse --only-properties | grep -E "(readonly .+ (Device(IsMounted|IsDrive|File|MountPaths) ).*|\}|.*\{)" | awk -v RS="};" '/Flash-Drive/'
node /org/freedesktop/UDisks/devices/sdc1 { interface org.freedesktop.UDisks.Device { readonly as DeviceMountPaths = ['/media/user/Flash-Drive']; readonly b DeviceIsMounted = true; readonly b DeviceIsDrive = false; readonly s DeviceFile = '/dev/sdc1';
通过以下方法获取节点 /org/freedesktop/UDisks/devices/sdc1
(将'/\/media\/user\/Flash-Drive/'替换为您的路径)。 $ gdbus introspect --system --dest org.freedesktop.UDisks --object-path /org/freedesktop/UDisks/devices --recurse --only-properties | grep -E "(readonly .+ (Device(IsMounted|IsDrive|File|MountPaths) ).*|\}|.*\{)" | awk -v RS="};" '/\/media\/user\/Flash-Drive/' | awk '/node/ {print $2}'
/org/freedesktop/UDisks/devices/sdc1
使用以下命令卸载:
gdbus call --system --dest org.freedesktop.UDisks --object-path /org/freedesktop/UDisks/devices/sdc1 --method org.freedesktop.UDisks.Device.FilesystemUnmount []
或者作为AllInOne(将'/\/media\/user\/Flash-Drive/'替换为您的路径):
gdbus call --system --dest org.freedesktop.UDisks --object-path $(gdbus introspect --system --dest org.freedesktop.UDisks --object-path /org/freedesktop/UDisks/devices --recurse --only-properties | grep -E "(readonly .+ (Device(IsMounted|IsDrive|File|MountPaths) ).*|\}|.*\{)" | awk -v RS="};" '/\/media\/user\/Flash-Drive/' | awk '/node/ {print $2}') --method org.freedesktop.UDisks.Device.FilesystemUnmount []

你也可以使用 --block-device 来获得一个稍微更加合理的接口。不过你仍然需要查找你需要的块设备。 - Oli