分类 技术 下的文章

在过去的几个星期,(几乎)每次都有消息 Ubuntu 15.04在启动时检测到系统程序错误 跑出来“欢迎”我。那时我是直接忽略掉它的,但是这种情况到了某个时刻,它就让人觉得非常烦人了!

检测到系统程序错误(System program problem detected)

你想立即报告这个问题吗?

我肯定地知道如果你是一个Ubuntu用户,你可能曾经也遇到过这个恼人的弹窗。在本文中,我们将探讨在Ubuntu 14.04和15.04中遇到"检测到系统程序错误(system program problem detected)"时 应该怎么办。

怎么解决Ubuntu中"检测到系统程序错误"的错误

那么这个通知到底是关于什么的?

大体上讲,它是在告知你,你的系统的一部分崩溃了。可别因为“崩溃”这个词而恐慌。这不是一个严重的问题,你的系统还是完完全全可用的。只是在之前的某个时刻某个程序崩溃了,而Ubuntu想让你决定要不要把这个问题报告给开发者,这样他们就能够修复这个问题。

那么,我们点了“报告错误”的按钮后,它以后就不再显示了?

不,不是的!即使你点了“报告错误”按钮,最后你还是会被一个如下的弹窗再次“欢迎”一下:

对不起,Ubuntu发生了一个内部错误是个Apport(LCTT 译注:Apport是Ubuntu中错误信息的收集报告系统,详见Ubuntu Wiki中的Apport篇),它将会进一步的打开网页浏览器,然后你可以通过登录或创建Launchpad帐户来填写一份漏洞(Bug)报告文件。你看,这是一个复杂的过程,它要花整整四步来完成。

但是我想帮助开发者,让他们知道这个漏洞啊 !

你这样想的确非常地周到体贴,而且这样做也是正确的。但是这样做的话,存在两个问题。第一,存在非常高的概率,这个漏洞已经被报告过了;第二,即使你报告了个这次崩溃,也无法保证你不会再看到它。

那么,你的意思就是说别报告这次崩溃了?

对,也不对。如果你想的话,在你第一次看到它的时候报告它。你可以在上面图片显示的“显示细节(Show Details)”中,查看崩溃的程序。但是如果你总是看到它,或者你不想报告漏洞(Bug),那么我建议你还是一次性摆脱这个问题吧。

修复Ubuntu中“检测到系统程序错误”的错误

这些错误报告被存放在Ubuntu中目录/var/crash中。如果你翻看这个目录的话,应该可以看到有一些以crash结尾的文件。

我的建议是删除这些错误报告。打开一个终端,执行下面的命令:

sudo rm /var/crash/*

这个操作会删除所有在/var/crash目录下的所有内容。这样你就不会再被这些报告以前程序错误的弹窗所扰。但是如果又有一个程序崩溃了,你就会再次看到“检测到系统程序错误”的错误。你可以再次删除这些报告文件,或者你可以禁用Apport来彻底地摆脱这个错误弹窗。

彻底地摆脱Ubuntu中的系统错误弹窗

如果你这样做,系统中任何程序崩溃时,系统都不会再通知你。如果你想问问我的看法的话,我会说,这不是一件坏事,除非你愿意填写错误报告。如果你不想填写错误报告,那么这些错误通知存不存在都不会有什么区别。

要禁止Apport,并且彻底地摆脱Ubuntu系统中的程序崩溃报告,打开一个终端,输入以下命令:

gksu gedit /etc/default/apport

这个文件的内容是:

# 设置0表示禁用Apportw,或者1开启它。
# 你可以用下面的命令暂时关闭它:
# sudo service apport start force_start=1
enabled=1

enabled=1改为enabled=0。保存并关闭文件。完成之后你就再也不会看到弹窗报告错误了。很显然,如果我们想重新开启错误报告功能,只要再打开这个文件,把enabled设置为1就可以了。

你的有效吗?

我希望这篇教程能够帮助你修复Ubuntu 14.04和Ubuntu 15.04中检测到系统程序错误的问题。如果这个小窍门帮你摆脱了这个烦人的问题,请让我知道。


via: http://itsfoss.com/how-to-fix-system-program-problem-detected-ubuntu/

作者:Abhishek 译者:XLCYun 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

ubuntu打开的正确方式(笑)

在这个快节奏的时代。能够使用最快速度最低代价完成任务具有非常重要的意义,对于现代开发者来说,Linux是生活中必不可少且不可替代的工具,如果我们在开发少或学习中少一些遇到环境的坑,会节省很多时间,潜伏在各种Linux群中数年,发现大家都有手贱(操作失误,笑),因此在本文中给出终极解决方案: 直接使用Ubuntu Live CD 来完成系统的启动。

那么最快的Linux安装办法又是什么呢?其实经过严谨的思考之后我个人觉得是不安装。我们可以准备从grub启动ubuntu操作系统把系统放到内存中,再预制出各种情况的环境包,也就是环境模块化,因为系统是在整个内存中所以速度非常非常快,需要模块化的内容并不多,比如说ssh vim tmux 为一组工具,开机后一个命令就可以激活工具包,不到几秒钟的时间即可完成,其他的如Chrome浏览器一类的都可以快速完成在内存上的安装。通过这种方式让环境更加灵活更加快速准备好开发环境。

这是一个思路上的变化,从我需要什么就安装什么一起都准备好给你用->变成了只启动基础的系统然后我需要什么我就后加载什么。

最后的准备在于容器,Docker 以及RKT与RunC的准备,在团队内可以秒级推送运行的环境。

本文依然有它的缺点: 主要体现在两个方面

  1. 如果默认驱动不好使会造成很多麻烦。
  2. 对于内存小的开发机器还是做快照比较好。最少4G内存,我们推荐内存在8G以上最好是16G或者32G内存的机器上采用此方案。

因为本方案整个操作系统都是加载到内存中的,硬盘速度即为内存的速度,我这里实测可以达到4.5Gb/s,所以你准备好屌丝逆袭(买不起SSD)秒杀高富帅了吗?

ubuntu

对于它的简单介绍可以参考这里。当然对于我本人而言选择Ubuntu主要原因仅仅是对他比较熟悉。并不限制使用什么发行版本。如果您要是选本方案搭建环境,并且选择其他发行版本请选择LiveCD尽量小一点的,如果能自己裁剪LiveCD就更好了,另外尽量选择64位架构。当然自己越熟悉越好。

虽然Ubuntu有一点不自由,但是我个人觉得包的质量管理还是非常好的,的确适合开发者使用。

Docker

官方:https://www.docker.com/

它对于我来说,几乎就像是水,如果没有他就没有今天的丰富多彩的运行方式,它可以让程序连同环境一起打包运行,使得部署备份等等非常方便,对于本次环境构建而言我们可以在个人的registry上备份自己的环境,只需要一小段时间就可以克隆回来。再加上现在各种永久免费的国内加速服务这种环境部署就是程序员天堂。更多细节请关注这里

在本文中我们使用单文件版本的Docker文件,方便可控。无任何累赘。本人不喜脚本安装。

RunC && RKT

这两种产品是libcontainer的代表。相对于Docker来说,它是一个容器只需要一个进程,对于Docker来说,他需要一个守护进程。在本文中(本博主)不评价任何产品的好坏,只说什么时候适合用什么。当然在我们这里利用了它启动方便,挂载方便的特性让我们的工作更方便更方便更方便!

由于现在RunC还没有发布1.0版本文档几乎没有,因此我这里会给出我的详细研究结果。至于RKT还是大家自己摸索,文档已经很全了。

CoreOS

作为专门运行容器的操作系统,稳定性可不属性都是前所未有,当然我们的容器可以跑在这个上面本文中会提及两个系统的兼容性方案。

  1. Ubuntu适合程序开发的情况。启动速度可能在1分钟左右(有点慢)。但是有图形界面,有定制基础环境的方案。
  2. CoreOS适合跑程序,启动速度在10秒以下适合释放更多内存来跑临时业务,做测试的时候实用此方案。

从Grub开始

什么是Grub

它可以装在硬盘上帮助你启动操作系统,几乎所有操作系统都可以,当然也包含本次的方案内容。安装方式有很多种。而且必须得根据自己的情况来安装。因为每个人电脑上的操作系统情况都不一样,有的已经有系统了。有的不想给自己装引导。可能先放到u盘上引导都有可能。因此这里不做安装方法上的更多描述可以自己根据情况到搜索引擎上搜索。

Grub 的安装

我之前是安装了windows,所以我直接安装了EasyBCD然后安装NeoGRUB来实现的。具体操作步骤如下:

  1. 下载安装EasyBCD
  2. 如图所示
  3. 安装重启电脑之后选择Grub启动项可以进入一个类似输入命令的界面即可确定完成安装。

Ubuntu 启动配置

启动准备

如果想要准备启动Ubuntu那么有三个关键要素,

  1. ubuntu-14.04.2-desktop-amd64.iso
  2. image中casper/vmlinuz.efi
  3. image中casper/initrd.lz

这三个文件作为启动的必要文件请放到分区中容易找到的地方。推荐做法:给自己的硬盘上开个EXT4 分区,然后把三个文件丢到里面去。

启动参数调试

工作中我们讲求流程,当然我们也需要一定的路程,我们不可能一次调整就成功把ISO启动起来。因此我们先加一个调试流程。

root (hd0,1)
kernel (hd0,1)/casper/vmlinuz.efi boot=casper iso-scan/filename=/ubuntu-14.04.2-desktop-amd64.iso ro quiet splash locate=en_US.UTF-8
initrd (hd0,1)/casper/initrd.lz
  1. 你需要看清楚把文件放到了第几块硬盘上,第几块分区上。组成参数为(hd0,1)(我的是0号硬盘第二个分区)。如果你实在分不清可以参考这里
  2. root (hd0,1) 设置GRUB的root设备
  3. kernel 命令套格式,变化参数 vmlinuz.efi 和 ubuntu-14.04.2-desktop-amd64.iso 要与你放到硬盘上的位置对应,可以使用Tab自动补全非常实用。
  4. initrd 依然是套格式找到对应硬盘傻姑娘的initrd.lz的位置。
  5. 如果出现错误了按会出现刚才的命令,多加修改直到成功启动。

启动参数放到硬盘中

如果是NeoGrub配置文件路径C:\NST\menu.lst,其他的请参考说明文档,一般都会有的。

配置文件写法:

timeout 3
default 0

title Ubuntu
root (hd0,1)
kernel (hd0,1)/casper/vmlinuz.efi boot=casper iso-scan/filename=/ubuntu-14.04.2-desktop-amd64.iso ro quiet splash locate=en_US.UTF-8
initrd (hd0,1)/casper/initrd.lz

3秒等待自动选择第一项,名称ubuntu 别的剩下的就是刚才调试内容的命令了。

完成刚需配置

刚醒需求配置是指在容器之外的刚醒需求配置,比如说编辑器,SSH等等工具箱。配置方法: APT

  1. 修改安装源:sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && apt-get update
  2. 安装你需要的软件包:apt-get install -y vim screen tmux ssh-server等等
  3. 调试你的环境看看是否好使,然后复制文件夹/var/cache/apt/archives中所有deb文件即为您刚才所有的安装包。复制到一个可以持久化的文件夹中等待使用。
  4. 回调环境: 每当您重新启动之后这些安装包即消失,想恢复,进入到上一步中复制到的文件夹中执行如下命令dpkg -i *即可安装预先准备好的软件
  5. 灵活使用,此步骤为发挥组合拳威力的一步。当您反复定制凝练您的安装包之后,会根据个人情况选择不同的目录来初始化您的环境,其结果是,又小又轻,非常可靠。再也不怕手贱导致环境崩坏,再加上外部的git服务保证工作内容的安全性基本上可以肯定的说:我们的环境与硬件与工作耦合度降低不少.
  6. 对于APT无法安装的内容,比如说JDK 与定制版本的Eclipse您可以通过下载完之后持久化保存到硬盘中,写一个脚本解压后放到硬盘中至于环境直接写入到profile中即可。
  7. 使用此方法之后假如您使用IDE真的会有一个非常非常大的速度提升,我打开Eclipse C/C++ 5秒钟即可。

容器安装配置

一般情况下我们安装Docker都是通过网上下载脚本安装,但是这种情况下我们推荐使用直接下载单文件版本的来完成安装安装脚本如下:

curl -sSL -O https://get.daocloud.io/docker/builds/Linux/x86_64/docker-latest
chmod +x docker-latest
mv docker-latest /usr/bin/docker
docker -d & 

在第三行中复制docker程序到任何Path下的文件夹内备用。在配置上,还是要吧/var/lib/docker放到可持久化的软连接下面。比如说按照下面的操作:

rm -rf /var/lib/docker
ln -s /isodevice/docker /var/lib/docekr 

按照这种方法操作可以让docker image 持久化保存在硬盘中。重启也能找回来。这里注意,如果您之前就实践了CoreOS 171.3 版本上的Docker它使用的是1.6版本他的存储文件格式与1.7的不同因此不通用。我就踩到这个坑了。接下来的操作就与Docker一样了。

注意:这个安装包: cgroup-lite_1.9_all.deb 一定要装,默认的光盘中就差这一个依赖,在下面的安装包中有要不就apt安装保存下来都可以。

材料准备

我在百度云盘中准备了三个文件,第一个是docker 1.7.1 第二个准别了vim screen ssh-server tmux CGroup的安装包。最后一个把我常用的Docker images 打包放出来了。其实在准备这个方案花最多时间就是在于精简依赖,最后发现只需要一个CGroup安装包。

总结

在本段文档中,我们给出了一个全新的使用Linux操作系统的思路不安装。并且做了一定的前期准备工作。启动了Linux操作系统做到本步骤如果您是新手就可以开始Linux的学习旅程了,如果您是需要此方案工作已经可以展开一般性质的工作了。
最后我真的拆掉我的三爽垃圾ssd(越用越慢)直接上内存。

方案合理要素:

  1. root权限过大。有时导致无法挽回的误操作。
  2. 现在的电脑内存不是很贵。大部分Linux电脑内存都在闲置。
  3. Linux操作系统如果每次执行的任务如果比较单一(一台物理机只给一个人用)真的不会很大。
  4. 给重新启动计算机赋予了新的意义。
  5. 真正超过SSD的速度,成本更低。(实测启动Eclipse C/C++ 仅需要5s)

UPDATE: 2015-08-31

QQ 6.3 由于版本低,已不能登录,以下教程已不适用,有想要折腾 wine QQ 的仅供参考。

Linux 上面玩 QQ 一直都是一个问题。Wine 算是一个解决方案,但是也有不少人失败了。由于 QQ 的特殊性,采取了一系列的保护措施,导致 QQ 这个 Windows 程序非常复杂,因此 Wine 在运行 QQ 时表现差强人意。本文将要安装的是 QQ6.3 ,更高的版本除非对 QQ 做出修改,否则很难安装成功,即使成功了,问题也挺多的(笔者已试验过 QQ7.4 安装)。写这个的目的主要是方便有人遇到问题截图提问,毕竟 Linux 的普及工作还得靠大家,对于日常聊天还是建议使用手机QQ 。

本文环境

  • Arch Linux (其他发行版仅供参考)
  • KDE4 & LXDE & GNOME (其它请自测)

准备工具

  • Wine
  • winetricks

简介

  • Wine 是一个在类 Unix 系统中运行 Microsoft Windows 程序的软件, Wine 的全称是 Wine Is Not Emulator 意为 Wine 不是一个模拟器,它通过 API 转换技术做出 Linux 上对应于 Windows 的函数,从而调用 DLL 运行 Windows 程序。
  • winetricks 是一个 script ,可以用来下载和安装各种在 Wine 运行时需要的部分 DLL 和框架。如 .NETVisual C++ runtime library 或微软和其他公司的闭源程序,使用 winetricks 你可以快速安装某些常用的Windows程序。

步骤

1.安装 Wine

$ sudo pacman -S wine

注意:64 位需启用 multilib 仓库才可安装 Wine ,去掉 [multilib] 及其 Include的 “#”即可

$ sudo nano /etc/pacman.conf

2.安装 winetricks

$ sudo pacman -S winetricks

3.获取 winetricks-zhverb 文件,更多详情请到: winetricks-zh

$ mkdir workforwine
$ cd workforwine
$ wget https://github.com/hillwoodroc/winetricks-zh/raw/master/verb/qq.verb

4.安装 QQ

$ WINEARCH=win32 winetricks qq

接下来是漫长的安装过程,会下载一系列需要的组件,将缓存在 ~/.cache/winetricks ,请耐心等待。或许你还可以试试 winetricks-zhwinetricks-zhwinetricks 的本地化版本,添加了更多国人可能用到的软件。

$ wget https://github.com/hillwoodroc/winetricks-zh/raw/master/winetricks-zh
$ chmod +x winetricks-zh
$ ./winetricks-zh

注意:若你觉得 安装QQ 这一步安装 monogecko 太慢,如下图:

installmono

installingmono

installgecko

根据配图我们可以知道 mono.NET 需要的包,而 gecko 则是 HTML 需要的包,并且 wine 也更建议我们使用我们发行版中的 monogecko 包,这有两个好处,一是更加符合自己的发行版,二是不用为每个 PREFIEX 单独安装,因此可以尝试以下操作,其他发行版仅供参考:

$ rm -rf ~/.wine
$ sudo pacman -S wine-mono
$ sudo pacman -S wine_gecko
$ WINEARCH=win32 winetricks qq

需要注意的几点

  • 请确保你安装有文泉驿字体 sudo pacman -S wqy-microhei
  • winetrickswinetricks-zh 安装的区别仅在于安装目录不同, winetricks 未指定位置时默认 ~/.wine ,而winetricks-zh 则安装QQ至 ~/.local/share/wineprefixes/qq
  • 有任何问题都可以直接删除上面提到的两个文件夹重来。
  • wine 的不稳定性,导致用 winetricks 安装字体有时可以解决,有时不可以,笔者试验了很多次以失败告终,希望有谁解决了可以告诉笔者。

其他解决方案

参考资料

无论是体积还是价值,数据都在不断增长。快速而可靠地备份和恢复数据正变得越来越重要。社会已经适应了技术的广泛使用,并懂得了如何依靠电脑和移动设备,但很少有人能够面对丢失重要数据的现实。在遭受数据损失的公司中,30% 的公司将在一年内损失一半市值,70% 的公司将在五年内停止交易。这更加凸显了数据的价值。

随着数据在体积上的增长,提高存储利用率尤为重要。从计算机的角度说,数据去重是一种特别的数据压缩技术,因为它可以消除重复数据的拷贝,所以这个技术可以提高存储利用率。

数据并不仅仅只有其创造者感兴趣。政府、竞争者、犯罪分子、偷窥者可能都热衷于获取你的数据。他们或许想偷取你的数据,从你那里进行敲诈,或看你正在做什么。因此,对于保护你的数据,加密是非常必要的。

所以,解决方法是我们需要一个可以去重的加密备份软件。

对于所有的用户而言,做文件备份是一件非常必要的事,至今为止许多用户还没有采取足够的措施来保护他们的数据。一台电脑不论是工作在一个合作的环境中,还是供私人使用,机器的硬盘可能在没有任何警告的情况下挂掉。另外,有些数据丢失可能是人为的错误所引发的。如果没有做经常性的备份,数据也可能不可避免地丢失,即使请了专业的数据恢复公司来帮忙。

这篇文章将对 6 个去重加密备份工具进行简要的介绍。

Attic

Attic 是一个可用于去重、加密,验证完整性的压缩备份程序,它是用 Python 写的。Attic 的主要目标是提供一个高效且安全的方式来备份数据。Attic 使用的数据去重技术使得它适用于每日备份,因为只需存储改变的数据。

其特点有:

  • 易用
  • 可高效利用存储空间,通过检查冗余的数据,对可变块大小的去重可以减少存储所用的空间
  • 可选的数据加密,使用 256 位的 AES 加密算法。数据的完整性和可靠性使用 HMAC-SHA256 来校验
  • 使用 SDSH 来进行离线备份
  • 备份可作为文件系统来挂载

网站: attic-backup.org

Borg

Borg 是 Attic 的一个分支。它是一个安全的开源备份程序,被设计用来高效地存储那些新的或修改过的数据。

Borg 的主要目标是提供一个高效、安全的方式来存储数据。Borg 使用的数据去重技术使得它适用于每日备份,因为只需存储改变的数据。认证加密使得它适用于存储在不完全可信的位置。

Borg 由 Python 写成。Borg 于 2015 年 5 月被创造出来,是为了解决让新的代码或重大的改变带入 Attic 的困难。

其特点包括:

  • 易用
  • 可高效利用存储空间,通过检查冗余的数据,对可变块大小的去重被用来减少存储所用的空间
  • 可选的数据加密,使用 256 位的 AES 加密算法。数据的完整性和可靠性使用 HMAC-SHA256 来校验
  • 使用 SDSH 来进行离线备份
  • 备份可作为文件系统来挂载

Borg 与 Attic 不兼容。

网站: borgbackup.github.io/borgbackup

Obnam

Obnam (OBligatory NAMe) 是一个易用、安全的基于 Python 的备份程序。备份可被存储在本地硬盘或通过 SSH SFTP 协议存储到网上。若使用了备份服务器,它并不需要任何特殊的软件,只需要使用 SSH 即可。

Obnam 通过将数据分成数据块,并单独存储它们来达到去重的目的,每次通过增量备份来生成备份,每次备份的生成就像是一次新的快照,但事实上是真正的增量备份。Obnam 由 Lars Wirzenius 开发。

其特点有:

  • 易用
  • 快照备份
  • 数据去重,跨文件,然后生成备份
  • 可使用 GnuPG 来加密备份
  • 向一个单独的仓库中备份多个客户端的数据
  • 备份检查点 (创建一个保存点,以每 100MB 或其他容量)
  • 包含多个选项来调整性能,包括调整 lru-size 或 upload-queue-size
  • 支持 MD5 校验算法来识别重复的数据块
  • 通过 SFTP 将备份存储到一个服务器上
  • 同时支持 push(即在客户端上运行) 和 pull(即在服务器上运行)

网站: obnam.org

Duplicity

Duplicity 以 tar 文件格式增量备份文件和目录,并使用 GnuPG 来进行加密,同时将它们上传到远程(或本地)的文件服务器上。它可以使用 ssh/scp、本地文件获取、rsync、 ftp 和 Amazon S3 等来传递数据。

因为 duplicity 使用了 librsync, 增量存档可以高效地利用存储空间,且只记录自从上次备份依赖改变的那部分文件。由于该软件使用 GnuPG 来加密或对这些归档文件进行进行签名,这使得它们免于服务器的监视或修改。

当前 duplicity 支持备份删除的文件,全部的 unix 权限,目录,符号链接, fifo 等。

duplicity 软件包还包含有 rdiffdir 工具。 Rdiffdir 是 librsync 的 rdiff 针对目录的扩展。它可以用来生成对目录的签名和差异,对普通文件也有效。

其特点有:

  • 使用简单
  • 对归档进行加密和签名(使用 GnuPG)
  • 高效使用带宽和存储空间,使用 rsync 的算法
  • 标准的文件格式
  • 可选择多种远程协议

    • 本地存储
    • scp/ssh
    • ftp
    • rsync
    • HSI
    • WebDAV
    • Amazon S3

网站: duplicity.nongnu.org

ZBackup

ZBackup 是一个通用的全局去重备份工具。

其特点包括:

  • 对存储数据并行进行 LZMA 或 LZO 压缩,在一个仓库中,你还可以混合使用 LZMA 和 LZO
  • 内置对存储数据的 AES 加密
  • 能够删除旧的备份数据
  • 可以使用 64 位的滚动哈希算法,使得文件冲突的数量几乎为零
  • 仓库中存储的文件是不可修改的,已备份的文件不会被修改。
  • 用 C++ 写成,只需少量的库文件依赖
  • 在生成环境中可以安全使用
  • 可以在不同仓库中进行数据交换而不必再进行压缩
  • 使用 64 位改进型 Rabin-Karp 滚动哈希算法

网站: zbackup.org

bup

bup 是一个用 Python 写的备份程序,其名称是 "backup" 的缩写。基于 git packfile 文件格式, bup 提供了一个高效的方式来备份一个系统,提供快速的增量备份和全局去重(在文件中或文件里,甚至包括虚拟机镜像)。

bup 在 LGPL 版本 2 协议下发行。

其特点包括:

  • 全局去重 (在文件之间或文件内部,甚至包括虚拟机镜像)
  • 使用一个滚动的校验和算法(类似于 rsync) 来将大文件分为多个数据块
  • 使用来自 git 的 packfile 文件格式
  • 直接写入 packfile 文件,以此提供快速的增量备份
  • 可以使用 "par2" 冗余来恢复冲突的备份
  • 可以作为一个 FUSE 文件系统来挂载你的 bup 仓库

网站: bup.github.io


via: http://www.linuxlinks.com/article/20150628060000607/BackupTools.html

译者:FSSlc 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

Vim是Linux上一个轻量级的通用文本编辑器。虽然它开始时的学习曲线对于一般的Linux用户来说可能很困难,但比起它的好处,这些付出完全是值得的。vim 可以通过完全可定制的插件来增加越来越多的功能。但是,由于它的功能配置比较难,你需要花一些时间去了解它的插件系统,然后才能够有效地去个性化定置Vim。幸运的是,我们已经有一些工具能够使我们在使用Vim插件时更加轻松。而我日常所使用的就是Vundle。

什么是Vundle

Vundle意即Vim Bundle,是一个vim插件管理器。Vundle能让你很简单地实现插件的安装、升级、搜索或者清除。它还能管理你的运行环境并且在标签方面提供帮助。在本教程中我们将展示如何安装和使用Vundle。

安装Vundle

首先,如果你的Linux系统上没有Git的话,先安装Git

接着,创建一个目录,Vim的插件将会被下载并且安装在这个目录上。默认情况下,这个目录为~/.vim/bundle。

$ mkdir -p ~/.vim/bundle 

现在,使用如下指令安装Vundle。注意Vundle本身也是一个vim插件。因此我们同样把vundle安装到之前创建的目录~/.vim/bundle下。

$ git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim 

配置Vundle

现在配置你的.vimrc文件如下:

set nocompatible              " 必需。 
filetype off                  " 必须。

" 在这里设置你的运行时环境的路径。
set rtp+=~/.vim/bundle/Vundle.vim

" 初始化vundle
call vundle#begin()

" 这一行应该永远放在开头。
Plugin 'gmarik/Vundle.vim'

" 这个示范来自https://github.com/gmarik/Vundle.vim README
Plugin 'tpope/vim-fugitive'

" 取自http://vim-scripts.org/vim/scripts.html的插件
Plugin 'L9'

" 该Git插件没有放在GitHub上。
Plugin 'git://git.wincent.com/command-t.git'

"本地计算机上的Git仓库路径 (例如,当你在开发你自己的插件时)
Plugin 'file:///home/gmarik/path/to/plugin'

" vim脚本sparkup存放在这个名叫vim的仓库下的一个子目录中。
" 将这个路径正确地设置为runtimepath。
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}

" 避免与L9发生名字上的冲突
Plugin 'user/L9', {'name': 'newL9'}

"所有的插件都应该在这一行之前。
call vundle#end()            " 必需。

容我简单解释一下上面的设置:默认情况下,Vundle将从github.com或者vim-scripts.org下载和安装vim插件。你也可以改变这个默认行为。

要从github安装插件:

Plugin 'user/plugin'

要从 http://vim-scripts.org/vim/scripts.html 处安装:

Plugin 'plugin_name'

要从另外一个git仓库中安装:

Plugin 'git://git.another_repo.com/plugin'

从本地文件中安装:

Plugin 'file:///home/user/path/to/plugin'

你同样可以定制其它东西,例如你的插件的运行时路径,当你自己在编写一个插件时,或者你只是想从其它目录——而不是~/.vim——中加载插件时,这样做就非常有用。

Plugin 'rstacruz/sparkup', {'rtp': 'another_vim_path/'}

如果你有同名的插件,你可以重命名你的插件,这样它们就不会发生冲突了。

Plugin 'user/plugin', {'name': 'newPlugin'}

使用Vum命令

一旦你用vundle设置好你的插件,你就可以通过几个vundle命令来安装、升级、搜索插件,或者清除没有用的插件。

安装一个新的插件

PluginInstall命令将会安装所有列在你的.vimrc文件中的插件。你也可以通过传递一个插件名给它,来安装某个的特定插件。

:PluginInstall
:PluginInstall <插件名>

清除没有用的插件

如果你有任何没有用到的插件,你可以通过PluginClean命令来删除它。

:PluginClean

查找一个插件

如果你想从提供的插件清单中安装一个插件,搜索功能会很有用。

:PluginSearch <文本>

在搜索的时候,你可以在交互式分割窗口中安装、清除、重新搜索或者重新加载插件清单。安装后的插件不会自动加载生效,要使其加载生效,可以将它们添加进你的.vimrc文件中。

总结

Vim是一个妙不可言的工具。它不单单是一个能够使你的工作更加顺畅高效的默认文本编辑器,同时它还能够摇身一变,成为现存的几乎任何一门编程语言的IDE。

注意,有一些网站能帮你找到适合的vim插件。猛击 http://www.vim-scripts.org, Github或者 http://www.vimawesome.com 获取新的脚本或插件。同时记得使用为你的插件提供的帮助。

和你最爱的编辑器一起嗨起来吧!


via: http://xmodulo.com/manage-vim-plugins.html

作者:Christopher Valerio 译者:XLCYun(袖里藏云) 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

通过运行在 Android 手机上的自制遥控器来控制你的家庭媒体播放器。

Kodi 是一款很优秀的软件,能够将几乎所有电脑变身成媒体中心。它可以播放音乐和视频,显示图片,甚至还能显示天气预报。为了在配置成家庭影院后方便使用,你可以通过手机 app 访问运行在连接到 Wi-Fi 的 XBMC 机器上的服务来控制它。可以找到很多这种工具,几乎覆盖所有智能手机系统。

XBMC

Kodi 原名叫做 XBMC,在你阅读这篇文章的时候,XBMC 已经成为历史。因为法律原因(因为名字 XBMC 或 X-Box Media Center 里引用了不再支持的过时硬件)项目组决定使用新的名字 Kodi。不过,除了名字,其他的都会保持原样。或者说除开通常新版本中所期待的大量新改进。这一般不会影响到遥控软件,它应该能在已有的 XBMC 系统和新的 Kodi 系统上都能工作。

我们目前已经配置好了一个用于播放音乐的 Kodi 系统,不过我们找到的所有 Kodi 遥控没一个好用的,特别是和媒体中心连接的电视没打开的时候。它们都有点太复杂了,集成了太多功能在手机的小屏幕上。我们希望能有这样的系统,从最开始就是设计成只用于访问音乐库和电台插件,所以我们决定自己实现一个。它不需要用到 Kodi 的所有功能,因为除了音乐以外的任务,我们可以简单地切换使用通用的 Kodi 遥控。我们的测试系统是一个刷了 RaspBMC 发行版的树莓派,但是我们要做的工具并不受限于树莓派或Kodi那个发行版,它应该可以匹配任何安装了相关插件的基于 Linux 的 Kodi 系统。

首先,遥控程序需要一个用户界面。大多数 Kodi 遥控程序都是独立的 app。不过对于我们要做的这个音乐控制程序,我们希望用户可以不用安装任何东西就可以使用。显然我们需要使用网页界面。Kodi 本身自带网页服务器,但是为了获得更多权限,我们还是使用了独立的网页框架。在同一台电脑上跑两个以上网页服务器没有问题,只不过它们不能使用相同的端口。

有几个网页框架可以使用。而我们选用 Bottle 是因为它是一个简单高效的框架,而且我们也确实用不到任何高级功能。Bottle 是一个 Python 模块,所以这也将是我们编写服务器模块的语言。

你应该能在软件包管理器里找到 Bottle。在基于 Debian 的系统(包括 RaspBMC)里,你可以通过下面的命令安装:

sudo apt-get install python-bottle

遥控程序实际上只是连接用户和系统的中间层。Bottle 提供了和用户交互的方式,而我们将通过 JSON API 来和 Kodi 交互。这样可以让我们通过发送 JSON 格式消息的方式去控制媒体播放器。

我们将用到一个叫做 xbmcjson 的简单 XBMC JASON API 封装。足够用来发送控制请求,而不需要关心实际的 JSON 格式以及和服务器通讯的无聊事。它没有包含在 PIP 包管理中,所以你得直接从 GitHub 安装:

git clone https://github.com/jcsaaddupuy/python-xbmc.git
cd python-xbmc
sudo python setup.py install

万事俱备,只欠代码。

先从 Bottle 开始

我们程序的基本结构:

from xbmcjson import XBMC
from bottle import route, run, template, redirect, static_file, request
import os
xbmc = XBMC("http://192.168.0.5/jsonrpc", "xbmc", "xbmc")
@route('/hello/<name>')
def index(name):
return template('<h1>Hello {{name}}!</h1>', name=name)
run(host="0.0.0.0", port=8000)

这样程序将连接到 Kodi(不过实际上用不到);然后 Bottle 会开始提供网站服务。在我们的代码里,它将监听主机 0.0.0.0(意味着允许所有主机连接)的端口 8000。它只设定了一个站点,就是 /hello/XXXX,这里的 XXXX 可以是任何内容。不管 XXXX 是什么都将作为参数名传递给 index()。然后再替换进去 HTML 网页模版。

你可以先试着把上面内容写到一个文件(我们取的名字是 remote.py),然后用下面的命令启动:

python remote.py

然后你可以在浏览器里访问 localhost:8000/hello/world 看看模版生效的效果。

@route() 用来设定网页服务器的路径,而函数 index() 会返回该路径的数据。通常是返回由模版生成的 HTML 页面,但是并不是说只能这样(后面会看到)。

随后,我们将给应用添加更多页面入口,让它变成一个全功能的 Kodi 遥控,但仍将采用相同代码结构。

XBMC JSON API 接口可以从和 Kodi 机器同网段的任意电脑上访问。也就是说你可以在自己的笔记本上开发,然后再布置到媒体中心上,而不需要浪费时间上传每次改动。

模版 - 比如前面例子里的那个简单模版 - 是一种结合 Python 和 HTML 来控制输出的方式。理论上,这俩能做很多很多事,但是会非常混乱。我们将只是用它们来生成正确格式的数据。不过,在开始动手之前,我们先得准备点数据。

Paste

Bottle 自带网页服务器,我们用它来测试遥控程序。不过,我们发现它性能有时不够好。当我们的遥控程序正式上线时,我们希望页面能更快一点显示出来。Bottle 可以和很多不同的网页服务器配合工作,而我们发现 Paste 用起来非常不错。而要使用的话,只要简单地安装(Debian 系统里的 python-paste 包),然后修改一下代码里的 run 调用:

run(host=hostname, port=hostport, server="paste")

你可以在 http://bottlepy.org/docs/dev/deployment.html 找到如何使用其他服务器的相关细节。

从 Kodi 获取数据

XBMC JSON API 分成 14 个命名空间:JSONRPC, Player, Playlist, Files, AudioLibrary, VideoLibrary, Input, Application, System, Favourites, Profiles, Settings, Textures 和 XBMC。每个都可以通过 Python 的 XBMC 对象访问(Favourites 除外,明显是个疏忽)。每个命名空间都包含许多方法用于对程序的控制。例如,Playlist.GetItems() 可以用来获取某个特定播放列表的内容。服务器会返回给我们 JSON 格式的数据,但 xbmcjson 模块会为我们转化成 Python 词典。

我们需要用到 Kodi 里的两个组件来控制播放:播放器和播放列表。播放器处理播放列表并在每首歌结束时从列表里取下一首。为了查看当前正在播放的内容,我们需要获取正在工作的播放器的 ID,然后根据它找到当前播放列表的 ID。这个可以通过下面的代码来实现:

def get_playlistid():
player = xbmc.Player.GetActivePlayers()
if len(player['result']) > 0:
playlist_data = xbmc.Player.GetProperties({"playerid":0, "properties":["playlistid"]})
if len(playlist_data['result']) > 0 and "playlistid" in playlist_data['result'].keys():
return playlist_data['result']['playlistid']
return -1

如果当前没有播放器在工作(就是说,返回数据的结果部分的长度是 0),或者当前播放器没有处理播放列表,这样的话函数会返回 -1。其他时候,它会返回当前播放列表的数字 ID。

当我们拿到当前播放列表的 ID 后,就可以获取该列表的细节内容。按照我们的需求,有两个重要的地方:播放列表里包含的项,以及当前播放所处的位置(已经播放过的项并不会从播放列表移除,只是移动当前播放位置)。

def get_playlist():
playlistid = get_playlistid()
if playlistid >= 0:
data = xbmc.Playlist.GetItems({"playlistid":playlistid, "properties": ["title", "album", "artist", "file"]})
position_data = xbmc.Player.GetProperties({"playerid":0, 'properties':["position"]})
position = int(position_data['result']['position'])
return data['result']['items'][position:], position
return [], -1

这样可以返回正在播放的项开始的列表(因为我们并不关心已经播放过的内容),而且也包含了用来从列表里移除项的位置信息。

Image

API 文档在这里:http://wiki.xbmc.org/?title=JSON-RPC_API/v6。它列出了所有支持的函数,但是关于具体如何使用的描述有点太简单了。

JSON

JSON 是 JavaScript Object Notation 的缩写,最初设计用于 JavaScript 对象的序列化。目前仍然起到这个作用,但是它也是用来编码任意数据的一种很好用的方式。

JSON 对象都是这样的格式:

{property1:value1, property2:value2, property3:value3}

支持任意数目的属性/值配对。对 Python 程序员来说,看上去和字典数据结构很相似,不过这两个确实很像。

在字典数据结构里,值本身可以是另一个 JSON 对象,或者一个列表,所以下面的格式也是正确的:

{"name":"Ben", "jobs":["cook", "bottle-washer"], "appearance": {"height":195, "skin":"fair"}}

JSON 通常在网络服务中用来发送和接收数据,并且大多数编程语言都能很好地支持,所以如果你熟悉 Python 的话,你应该可以使用你熟悉的编程语言调用相同的接口来轻松地控制 Kodi。

整合到一起

把之前的功能连接到 HTML 页面很简单:

@route('/juke')
def index():
current_playlist, position = get_playlist()
return template('list', playlist=current_playlist, offset = position)

只需要抓取播放列表(调用我们之前定义的函数),然后将结果传递给负责显示的模版。

负责显示列表数据的模版的主要部分是:

<h2>Currently Playing:</h2>
% if playlist is not None:
% position = offset
% for song in playlist:
<strong> {{song['title']}} </strong>
% if song['type'] == 'unknown':
Radio
% else:
{{song['artist'][0]}}
% end
% if position != offset:
<a href="/remove/{{position}}">remove</a>
% else:
<a href="/skip/{{position}}">skip</a>
% end
<br>
% position += 1
% end

可以看到,模版大部分是用 HTML 写的,只有一小部分用来控制输出的其他代码。用两个大括号括起来的变量是输出位置(像我们在第一个 'hello world' 例子里看到的)。你也可以嵌入以百分号开头的 Python 代码。因为没有缩进,你需要用一个 % end 来结束当前的代码块(就像循环或 if 语句)。

这个模版首先检查列表是否为空,然后遍历里面的每一项。每一项会用粗体显示歌曲名字,然后是艺术家名字,然后是一个是否跳过(如果是当前正在播的歌曲)或从列表移除的链接。所有歌曲的类型都是 'song',如果类型是 'unknown',那就不是歌曲而是网络电台。

/remove/ 和 /skip/ 路径只是简单地封装了 XBMC 控制功能,在改动生效后重新加载 /juke:

@route('/skip/<position>')
def index(position):
print xbmc.Player.GoTo({'playerid':0, 'to':'next'})
redirect("/juke")
@route('/remove/<position>')
def index(position):
playlistid = get_playlistid()
if playlistid >= 0:
xbmc.Playlist.Remove({'playlistid':int(playlistid), 'position':int(position)})
redirect("/juke")

当然,如果不能往列表里添加歌曲的话那这个列表管理功能也不行。

因为一旦播放列表结束,它就消失了,所以你需要重新创建一个,这会让事情复杂一些。而且有点让人迷惑的是,播放列表是通过调用 Playlist.Clear() 方法来创建的。这个方法也还用来删除包含网络电台(类型是 unknown)的播放列表。另一个麻烦的地方是列表里的网络电台开始播放后就不会停,所以如果当前在播网络电台,也会需要清除播放列表。

这些页面包含了指向 /play/ 的链接来播放歌曲。通过下面的代码处理:

@route('/play/<id>')
def index(id):
playlistid = get_playlistid()
playlist, not_needed= get_playlist()
if playlistid < 0 or playlist[0]['type'] == 'unknown':
xbmc.Playlist.Clear({"playlistid":0})
xbmc.Playlist.Add({"playlistid":0, "item":{"songid":int(id)}})
xbmc.Player.open({"item":{"playlistid":0}})
playlistid = 0
else:
xbmc.Playlist.Add({"playlistid":playlistid, "item":{"songid":int(id)}})
remove_duplicates(playlistid)
redirect("/juke")

最后一件事情是实现 remove\_duplicates 调用。这并不是必须的 - 而且还有人并不喜欢这个 - 不过可以保证同一首歌不会多次出现在播放列表里。

我们也实现了一些页面用来列出收藏歌曲里所有艺术家,以及列出指定艺术家的歌曲和专辑。这些都非常简单,和 /juke 页面基本类似。

Image

还需要处理一下 UI,不过功能已经有了。

日志

通常拿到 XBMC JSON API 并不清楚能用来做什么,而且它的文档也有点模糊。找出如何使用的一种方式是看别的遥控程序是怎么做的。如果打开日志功能,就可以在使用其他遥控程序的时候看到哪个 API 被调用了,然后就可以应用到在自己的代码里。

要打开日志功能,把 Kodi 媒体中心 接到显示器上,再依次进入设置 > 系统 > 调试,打开允许调试日志。在打开日志功能后,还需要登录到 Kodi 机器上(比如通过 SSH),然后就可以查看日志了。日志文件的位置应该显示在 Kodi 界面左上角。在 RaspBMC 系统里,文件位置是 /home/pi/.xbmc/temp/xbmc.log。你可以通过下面的命令实时监视哪个 API 接口被调用了:

cd /home/pi/.xbmc/temp
tail -f xbmc.log | grep "JSON"

增加功能

上面的代码都是用来播放 Kodi 媒体库里的歌曲的,但我们还希望能播放网络电台。每个插件都有自己的独立 URL 可以通过普通的 XBMC JSON 命令来获取信息。举个例子,要从电台插件里获取选中的电台,可以使用;

@route('/radio/')
def index():
my_stations = xbmc.Files.GetDirectory({"directory":"plugin://plugin.audio.radio_de/stations/my/", "properties":
["title","thumbnail","playcount","artist","album","episode","season","showtitle"]})
if 'result' in my_stations.keys():
return template('radio', stations=my_stations['result']['files'])
else:
return template('error', error='radio')

这样可以返回一个可以和歌曲一样能添加到播放列表的文件。不过,这些文件能一直播下去,所以(之前说过)在添加其他歌曲的时候需要重新创建列表。

共享歌曲

除了伺服页面模版,Bottle 还支持静态文件,方便用于那些不会因为用户输入而改变的内容。可以是 CSS 文件,一张图片或是一首 MP3 歌曲。在我们的简单遥控程序里(目前)还没有任何用来美化的 CSS 或图片,不过我们增加了一个下载歌曲的途径。这个可以让媒体中心变成一个存放歌曲的 NAS 盒子。在需要传输大量数据的时候,最好还是用类似 Samba 的功能,但只是下几首歌到手机上的话使用静态文件也是很好的方式。

通过歌曲 ID 来下载的 Bottle 代码:

@route('/download/<id>')
def index(id):
data = xbmc.AudioLibrary.GetSongDetails({"songid":int(id), "properties":["file"]})
full_filename = data['result']['songdetails']['file']
path, filename = os.path.split(full_filename)
return static_file(filename, root=path, download=True)

应用的时候,只需要为 /songsby/ 页面里的相应 ID 加个链接。

我们已经把所有的代码过了一遍,不过还需要一点工作来把它们集合到一起。可以自己去 GitHub 页面 https://github.com/ben-ev/xbmc-remote 看下。

设置
我们的遥控程序已经开发完成,还需要保证让它在媒体中心每次开机的时候都能启动。有几种方式,最简单的是在 /etc/rc.local 里增加一行命令来启动。我们的文件位置在 /opt/xbmc-remote/remote.py,其他文件也和它一起。然后在 /etc/rc.local 最后的 exit 0 之前增加了下面一行。

cd /opt/xbmc-remote && python remote.py &

GitHub
这个项目目前还只是个架子,但是 - 我们运营杂志就意味着没有太多自由时间来编程。不过,我们启动了一个 GitHub 项目,希望能持续完善, 而如果你觉得这个项目有用的话,欢迎做出贡献。

要查看最新的进展,请访问 https://github.com/ben-ev/xbmc-remote 看看所处的状态。你可以从页面里获取最新的代码,或者通过命令行复制。

如果你希望改善它,可以复制项目到你自己的分支开发,然后在功能完成后发起合并请求。关于如何使用 GitHub 的更多信息,请访问 https://github.com/features


via: http://www.linuxvoice.com/xbmc-build-a-remote-control/

作者:Ben Everard 译者:zpl1025 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出