文件系统使用指标

我无法找到合适的实用程序来指示面板上的文件系统使用情况(分区的可用空间百分比)。

我并不期待安装任何糟糕的桌面管理工具,而是一个简单的指标。

我感谢您的所有建议。

编辑:

1.新的答案

虽然可以使用此底部的答案(参见[2.] ),但它会导致在首选项窗口中设置带有附加选项的ppa -version。

在此处输入图像描述

在此处输入图像描述

选项包括:

  • 在一个窗口中设置所有别名
  • 设置面板图标的主题颜色:

    在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

  • 设置警告阈值
  • 在通知中显示有关新安装/已连接卷的信息:

    在此处输入图像描述

  • 在启动时运行

此外,指示器现在包括为其他发行版(如xfce)设置的较小(宽度)图标,将根据窗口管理器自动应用该图标。

在此处输入图像描述

安装:

 sudo add-apt-repository ppa:vlijm/spaceview sudo apt-get update sudo apt-get install spaceview 


2.老答复

下面的脚本是一个列出您的设备并显示其使用情况的指示器。 每十秒钟更新一次信息(如有必要)。

在此处输入图像描述

此外

  • 指示灯正在运行时,您可以选择要在图标中显示的设备。 下次运行指示器时将记住该设备:

    在此处输入图像描述

    ![在此处输入图像说明

    在此处输入图像描述

  • 对于一个或多个(或所有)设备,您可以设置替代名称(“自定义名称”),在脚本的头部设置

    举个例子,这个:

     alias = [ ["sdc1", "stick"], ["sdb1", "External"], ["sda2", "root"], ["sda4", "ntfs1"], ["sda5", "ntfs2"], ["//192.168.0.104/media", "netwerk media"], ["//192.168.0.104/werkmap_documenten", "netwerk docs"], ] 

    将会呈现:

    在此处输入图像描述

  • 你可以设置一个门槛 ; 如果您的任一设备的可用空间低于该设备,您将收到警告:

    在此处输入图像描述

  • 插入/拔出的设备将在10秒内从menulist添加/删除。

剧本

 #!/usr/bin/env python3 import subprocess import os import time import signal import gi gi.require_version('Gtk', '3.0') gi.require_version('AppIndicator3', '0.1') from gi.repository import Gtk, AppIndicator3, GObject from threading import Thread #--- set alias names below in the format [[device1, alias1], [device2, alias2]] #--- just set alias = [] to have no custom naming alias = [] #--- set the threshold to show a warning below #--- set to 0 to have no warning threshold = 17 #--- currpath = os.path.dirname(os.path.realpath(__file__)) prefsfile = os.path.join(currpath, "showpreferred") class ShowDevs(): def __init__(self): self.default_dev = self.get_showfromfile() self.app = 'show_dev' iconpath = currpath+"/0.png" self.indicator = AppIndicator3.Indicator.new( self.app, iconpath, AppIndicator3.IndicatorCategory.OTHER) self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) self.indicator.set_menu(self.create_menu()) self.indicator.set_label("Starting up...", self.app) self.update = Thread(target=self.check_changes) self.update.setDaemon(True) self.update.start() def check_changes(self): state1 = None while True: self.state2 = self.read_devices() if self.state2 != state1: self.update_interface(self.state2) state1 = self.state2 time.sleep(10) def update_interface(self, state): warning = False; self.newmenu = [] for dev in state: mention = self.create_mention(dev) name = mention[0]; deci = mention[2]; n = mention[1] if n <= threshold: warning = True try: if self.default_dev in name: newlabel = mention[3] newicon = currpath+"/"+str(10-deci)+".png" except TypeError: pass self.newmenu.append(name+" "+str(n)+"% free") if warning: newlabel = "Check your disks!" newicon = currpath+"/10.png" try: self.update_indicator(newlabel, newicon) except UnboundLocalError: labeldata = self.create_mention(state[0]) newlabel = labeldata[3] newicon = currpath+"/"+str(10-labeldata[2])+".png" self.update_indicator(newlabel, newicon) GObject.idle_add(self.set_new, priority=GObject.PRIORITY_DEFAULT) def update_indicator(self, newlabel, newicon): GObject.idle_add(self.indicator.set_label, newlabel, self.app, priority=GObject.PRIORITY_DEFAULT) GObject.idle_add(self.indicator.set_icon, newicon, priority=GObject.PRIORITY_DEFAULT) def set_new(self): for i in self.initmenu.get_children(): self.initmenu.remove(i) for item in self.newmenu: add = Gtk.MenuItem(item) add.connect('activate', self.change_show) self.initmenu.append(add) menu_sep = Gtk.SeparatorMenuItem() self.initmenu.append(menu_sep) self.item_quit = Gtk.MenuItem('Quit') self.item_quit.connect('activate', self.stop) self.initmenu.append(self.item_quit) self.initmenu.show_all() def change_show(self, *args): index = self.initmenu.get_children().index(self.initmenu.get_active()) self.default_dev = self.newmenu[index].split()[0] open(prefsfile, "wt").write(self.default_dev) self.update_interface(self.read_devices()) def create_mention(self, dev): name = dev[1] if dev[1] else dev[0] n = dev[2]; deci = round(dev[2]/10) newlabel = name+" "+str(n)+"% free" return (name, n, deci, newlabel) def create_menu(self): # create initial basic menu self.initmenu = Gtk.Menu() self.item_quit = Gtk.MenuItem('Quit') self.item_quit.connect('activate', self.stop) self.initmenu.append(self.item_quit) self.initmenu.show_all() return self.initmenu def read_devices(self): # read the devices, look up their alias and the free sapace devdata = [] data = subprocess.check_output(["df", "-h"]).decode("utf-8").splitlines() relevant = [l for l in data if all([ any([l.startswith("/dev/"), l.startswith("//")]), not "/loop" in l]) ] for dev in relevant: data = dev.split(); name = data[0]; pseudo = None free = 100-int([s.strip("%") for s in data if "%" in s][0]) for al in alias: if al[0] in name: pseudo = al[1] break devdata.append((name, pseudo, free)) return devdata def get_showfromfile(self): # read the preferred default device from file try: defdev = open(prefsfile).read().strip() except FileNotFoundError: defdev = None return defdev def stop(self, source): Gtk.main_quit() ShowDevs() GObject.threads_init() signal.signal(signal.SIGINT, signal.SIG_DFL) Gtk.main() 

图标

在此处输入图像描述 0.png

在此处输入图像描述 1.png

在此处输入图像描述 2.png

在此处输入图像描述 3.png

在此处输入图像描述 4.png

在此处输入图像描述 5.png

在此处输入图像描述 6.png

在此处输入图像描述 7.png

在此处输入图像描述 8.png

在此处输入图像描述 9.png

在此处输入图像描述 10.png

配置

设置很简单:

  • 将脚本复制到空文件中,将其另存为showusage.py
  • 将上面的图标(在其标签中完全命名)保存到与脚本相同的目录中(右键单击>另存为)
  • 在脚本的headsection中,设置(可能的)替代名称( aliasses )。 下面是一个例子:

     alias = [ ["sda2", "root"], ["sdb1", "External"] ] 

    如果要更改设备,请使用:

     alias = [] 

    ...如果需要,请更改阈值以显示警告:

     #--- set the threshold to show a warning below (% free, in steps of 10%) #--- set to 0 to have no warning threshold = 10 

    而已

运行它

要使用该指示器,请运行以下命令:

 python3 /path/to/showusage.py 

要将其添加到启动应用程序,请使用以下命令:

 /bin/bash -c "sleep 10 && python3 /path/to/showusage.py" 

选择Applications:Dash> Startup Applications> Add,添加上面的命令。

免责声明:我是本指标的作者,是针对此特定问题编写的

2016年10月29日更新

指示器现在具有卸载function,并且通过引用每个分区的UUID而不是块设备名称(例如sda1使别名变得唯一。 请参阅相关的错误报告

更新,2016年10月8日

该指标现在处于2.0版本,增加了一些function并拥有自己的PPA。

要从PPA安装,请在终端中使用以下步骤:

  1. sudo apt-add-repository ppa:udisks-indicator-team/ppa
  2. sudo bash -c 'apt-get update && apt-get install udisks-indicator'

如发行说明中所述,function包括:

  • 菜单条目的图标:每个分区/设备都附有适当的图标。 如果设备是usb磁盘,则使用可移动媒体图标,如果是iso映像 – 使用光盘图标,显然硬盘驱动器/ SSD分区有驱动器图标。
  • 用法现在以百分比和人类可读值(功率1024)显示。
  • 通过使用栏进行图形表示(非常感谢Mateo Salta的想法)
  • “首选项”对话框:用户可以关闭每个菜单项不希望看到的某些字段。 如果附加了大量分区,这可以保持指示器菜单清洁。 (感谢Zacharee的要求)
  • 文本间距:使用默认的Ubuntu字体和Monospace字体,文本条目间隔良好,外观更清晰,增强了信息的可读性。
  • 无法安装案例分区中的通知气泡

以下是默认Ubuntu图标主题的屏幕截图: 在此处输入图像描述

Ubuntu Kylin图标主题

在此处输入图像描述

关闭所有可选字段

在此处输入图像描述

设计选择和其他想法:

在制作这个指标时,我希望能够实现适合高级和休闲用户的实用工具。 我试图解决一些我注意到新用户处理命令行工具时可能遇到的问题。 此外,该实用程序力求多用途。

“首选项”对话框允许使指示符变得复杂和/或与用户期望的一样简单。 这也是一个特定的设计决定,避免在顶部面板上贴上标签,这样就不会占用用户的顶部面板空间太多。 此外,该指标力求成为多用途实用程序,允许安装分区以及打开各自的目录。 这不仅可以用作磁盘使用实用程序,还可以用作快速打开目录的导航实用程序。

用户也可以方便地知道哪个分区驻留在哪个磁盘上,从而避免了通过命令行实用程序(如mount进行安装时经常出现的混乱。 相反,它为此目的使用udisksctl (以及从UDisks2守护程序获取信息,因此命名)。 它不执行的唯一任务是卸载,或者这个原因包括Open Disks Utility菜单项。

虽然最初我努力使它类似于iStat menulet,但该项目偏离了这一目标 – 该指标在其设计和目的上是独一无二的。 我希望它对许多用户有用,并使他们的Ubuntu体验更加愉快。


udisks-indicator(原始答案)

使用Unity桌面显示磁盘使用情况的Ubuntu指示器 示例截图

概观

这个带有Unity的Ubuntu指示器可以轻松查看有关已安装分区的信息。 它力求在视觉上类似于OS X的iStat菜单3菜单。

参赛作品按顺序排列:

  • 划分
  • 别名(如果由用户设置)
  • 分区所属的磁盘驱动器
  • 分区的挂载点(目录)
  • %用法

单击每个分区条目将在默认文件管理器中打开分区的mountpoint

“Unmounted Partitions”菜单列出了系统当前未安装的所有分区。 单击该子菜单中的任何条目将自动挂载该分区,通常是/media/username/drive-id文件夹

指示器使用随系统提供的默认图标,因此当您使用Unity Tweak Tool或其他方法更改图标主题时,图标应该会发生变化

注意 :如果要同时添加多个别名,而不是通过“Make Alias”选项逐个添加,可以通过编辑~/.partition_aliases.json配置文件来实现。 格式如下:

 { "sda1": "Alias 1", "sda2": "Alias 2", "sdb1": "Alias 3" } 

安装

PPA易于安装即将推出。 。 。

同时,这里有替代步骤:

  1. cd /tmp
  2. wget https://github.com/SergKolo/udisks-indicator/archive/master.zip
  3. unzip master.zip
  4. sudo install udisks-indicator-master/udisks-indicator /usr/bin/udisks-indicator
  5. sudo install udisks-indicator-master/udisks-indicator.desktop /usr/share/applications/udisks-indicator.desktop

所有这些步骤都可以放在一个很好的小安装脚本中:

 #!/bin/bash cd /tmp rm master.zip* wget https://github.com/SergKolo/udisks-indicator/archive/master.zip unzip master.zip install udisks-indicator-master/udisks-indicator /usr/bin/udisks-indicator install udisks-indicator-master/udisks-indicator.desktop /usr/share/applications/udisks-indicator.desktop 

源代码

具有此指标基本function的原始源代码(版本v1.0)可在下面找到。 有关最新function,请检查此项目的GitHub存储库 。 请报告任何function请求以及GitHub上的错误。

/usr/bin/udisks-indicator

 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Author: Serg Kolo , contact: 1047481448@qq.com # Date: September 27 , 2016 # Purpose: appindicator for displaying mounted filesystem usage # Tested on: Ubuntu 16.04 LTS # # # Licensed under The MIT License (MIT). # See included LICENSE file or the notice below. # # Copyright © 2016 Sergiy Kolodyazhnyy # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import gi gi.require_version('AppIndicator3', '0.1') from gi.repository import GLib as glib from gi.repository import AppIndicator3 as appindicator from gi.repository import Gtk as gtk from os import statvfs #from collections import OrderedDict import subprocess import shutil import dbus import json import os class UdisksIndicator(object): def __init__(self): self.app = appindicator.Indicator.new( 'udisks-indicator', "drive-harddisk-symbolic.svg", appindicator.IndicatorCategory.HARDWARE ) if not self.app.get_icon(): self.app.set_icon("drive-harddisk-symbolic") self.app.set_status(appindicator.IndicatorStatus.ACTIVE) filename = '.partition_aliases.json' user_home = os.path.expanduser('~') self.config_file = os.path.join(user_home,filename) self.cache = self.get_partitions() self.make_menu() self.update() def update(self): timeout = 5 glib.timeout_add_seconds(timeout,self.callback) def callback(self): if self.cache != self.get_partitions(): self.make_menu() self.update() def make_menu(self,*args): """ generates entries in the indicator""" if hasattr(self, 'app_menu'): for item in self.app_menu.get_children(): self.app_menu.remove(item) self.app_menu = gtk.Menu() partitions = self.get_partitions() for i in partitions: part = "Partition: " + i[0] alias = self.find_alias(i[0]) drive = "\nDrive: " + i[1] mount = "\nMountPoint: " + i[2] usage = "\n%Usage: " + i[3] item = part + drive + mount + usage if alias: alias = "\nAlias: " + alias item = part + alias + drive + mount + usage self.menu_item = gtk.MenuItem(item) self.menu_item.connect('activate',self.open_mountpoint,i[2]) self.app_menu.append(self.menu_item) self.menu_item.show() self.separator = gtk.SeparatorMenuItem() self.app_menu.append(self.separator) self.separator.show() self.unmounted = gtk.MenuItem('Unmounted Partitions') self.unmounted_submenu = gtk.Menu() self.unmounted.set_submenu(self.unmounted_submenu) for i in self.get_unmounted_partitions(): # TODO: add type checking, prevent swap part = "Partition: " + i[0] alias = self.find_alias(i[0]) drive = "\nDrive: " + i[1] label = part + drive if alias: alias = "\nAlias: " + alias label = part + alias + drive self.menu_item = gtk.MenuItem(label) self.menu_item.connect('activate',self.mount_partition,i[0]) self.unmounted_submenu.append(self.menu_item) self.menu_item.show() self.separator = gtk.SeparatorMenuItem() self.unmounted_submenu.append(self.separator) self.separator.show() self.app_menu.append(self.unmounted) self.unmounted.show() self.separator = gtk.SeparatorMenuItem() self.app_menu.append(self.separator) self.separator.show() self.make_part_alias = gtk.MenuItem('Make Alias') self.make_part_alias.connect('activate',self.make_alias) self.app_menu.append(self.make_part_alias) self.make_part_alias.show() user_home = os.path.expanduser('~') desktop_file = '.config/autostart/udisks-indicator.desktop' full_path = os.path.join(user_home,desktop_file) label = 'Start Automatically' if os.path.exists(full_path): label = label + ' \u2714' self.autostart = gtk.MenuItem(label) self.autostart.connect('activate',self.toggle_auto_startup) self.app_menu.append(self.autostart) self.autostart.show() self.open_gnome_disks = gtk.MenuItem('Open Disks Utility') self.open_gnome_disks.connect('activate',self.open_disks_utility) self.app_menu.append(self.open_gnome_disks) self.open_gnome_disks.show() self.quit_app = gtk.MenuItem('Quit') self.quit_app.connect('activate', self.quit) self.app_menu.append(self.quit_app) self.quit_app.show() self.app.set_menu(self.app_menu) def mount_partition(self,*args): # TODO: implement error checking for mounting return self.run_cmd(['udisksctl','mount','-b','/dev/' + args[-1]]) def get_mountpoint_usage(self,mountpoint): fs = statvfs(mountpoint) usage = 100*(float(fs.f_blocks)-float(fs.f_bfree))/float(fs.f_blocks) return str("{0:.2f}".format(usage)) def get_partitions(self): objects = self.get_dbus('system', 'org.freedesktop.UDisks2', '/org/freedesktop/UDisks2', 'org.freedesktop.DBus.ObjectManager', 'GetManagedObjects', None) partitions = [] for item in objects: try: if 'block_devices' in str(item): drive = self.get_dbus_property('system', 'org.freedesktop.UDisks2', item, 'org.freedesktop.UDisks2.Block', 'Drive') if drive == '/': continue mountpoint = self.get_mountpoint(item) if not mountpoint: continue mountpoint = mountpoint.replace('\x00','') drive = str(drive).split('/')[-1] usage = self.get_mountpoint_usage(mountpoint) part = str(item.split('/')[-1]) partitions.append((part,drive,mountpoint,usage)) except Exception as e: #print(e) pass # returning list of tuples partitions.sort() return partitions def get_mountpoint(self,dev_path): try: data = self.get_dbus_property( 'system', 'org.freedesktop.UDisks2', dev_path, 'org.freedesktop.UDisks2.Filesystem', 'MountPoints')[0] except Exception as e: #print(e) return None else: if len(data) > 0: return ''.join([ chr(byte) for byte in data]) def get_unmounted_partitions(self): objects = self.get_dbus('system', 'org.freedesktop.UDisks2', '/org/freedesktop/UDisks2', 'org.freedesktop.DBus.ObjectManager', 'GetManagedObjects', None) partitions = [] for item in objects: try: if 'block_devices' in str(item): drive = self.get_dbus_property('system', 'org.freedesktop.UDisks2', item, 'org.freedesktop.UDisks2.Block', 'Drive') if drive == '/': continue mountpoint = self.get_mountpoint(item) if mountpoint: continue drive = str(drive).split('/')[-1] part = str(item.split('/')[-1]) if not part[-1].isdigit(): continue partitions.append((part,drive)) #print(partitions) except Exception as e: #print(e) pass partitions.sort() return partitions def get_dbus(self,bus_type,obj,path,interface,method,arg): if bus_type == "session": bus = dbus.SessionBus() if bus_type == "system": bus = dbus.SystemBus() proxy = bus.get_object(obj,path) method = proxy.get_dbus_method(method,interface) if arg: return method(arg) else: return method() def get_dbus_property(self,bus_type,obj,path,iface,prop): if bus_type == "session": bus = dbus.SessionBus() if bus_type == "system": bus = dbus.SystemBus() proxy = bus.get_object(obj,path) aux = 'org.freedesktop.DBus.Properties' props_iface = dbus.Interface(proxy,aux) props = props_iface.Get(iface,prop) return props def make_alias(self,*args): partitions = [ i[0] for i in self.get_partitions() ] combo_values = '|'.join(partitions) #print(combo_values) command=[ 'zenity','--forms','--title','Make Alias', '--add-combo','Partition','--combo-values', combo_values,'--add-entry','Alias' ] user_input = self.run_cmd(command) if not user_input: return alias = user_input.decode().strip().split('|') existing_values = None if os.path.isfile(self.config_file): with open(self.config_file) as conf_file: try: existing_values = json.load(conf_file) except ValueError: pass with open(self.config_file,'w') as conf_file: if existing_values: existing_values[alias[0]] = alias[1] else: existing_values = {alias[0]:alias[1]} #print(existing_values) json.dump(existing_values,conf_file,indent=4,sort_keys=True) def find_alias(self,part): if os.path.isfile(self.config_file): with open(self.config_file) as conf_file: try: aliases = json.load(conf_file) except ValueError: pass else: if part in aliases: return aliases[part] else: return None def toggle_auto_startup(self,*args): user_home = os.path.expanduser('~') desktop_file = '.config/autostart/udisks-indicator.desktop' full_path = os.path.join(user_home,desktop_file) if os.path.exists(full_path): os.unlink(full_path) else: original = '/usr/share/applications/udisks-indicator.desktop' if os.path.exists(original): shutil.copyfile(original,full_path) self.make_menu() def open_mountpoint(self,*args): pid = subprocess.Popen(['xdg-open',args[-1]]).pid def open_disks_utility(self,*args): pid = subprocess.Popen(['gnome-disks']).pid def run_cmd(self, cmdlist): """ Reusable function for running external commands """ new_env = dict(os.environ) new_env['LC_ALL'] = 'C' try: stdout = subprocess.check_output(cmdlist, env=new_env) except subprocess.CalledProcessError: pass else: if stdout: return stdout def run(self): """ Launches the indicator """ try: gtk.main() except KeyboardInterrupt: pass def quit(self, data=None): """ closes indicator """ gtk.main_quit() def main(): """ defines program entry point """ indicator = UdisksIndicator() indicator.run() if __name__ == '__main__': main() 

/usr/share/applications/udisks-indicator.desktop

 [Desktop Entry] Version=1.0 Name=Udisks Indicator Comment=Indicator for reporting partition information Exec=udisks-indicator Type=Application Icon=drive-harddisk-symbolic.svg Terminal=false 

附加信息:

Ubuntu Mate 16.04测试:

在此处输入图像描述

Gnome用户需要扩展(KStatusNotifierItem / AppIndicator支持)才能使指标正常运行:

在此处输入图像描述

安装Sysmonitor指标 :

 sudo add-apt-repository ppa:fossfreedom/indicator-sysmonitor sudo apt-get update sudo apt-get install indicator-sysmonitor 

它有“文件系统中的可用空间”选项。