分类 技术 下的文章

 title=

一般情况下,常规用途的 Linux 发行版在开机启动时拉起各种相关服务进程,包括许多你可能无需使用的服务,例如 蓝牙 bluetooth 、Avahi、 调制解调管理器 ModemManager 、ppp-dns(LCTT 译注:此处作者笔误 ppp-dns 应该为 pppd-dns) 等服务进程,这些都是什么东西?用于哪里,有何功能?

Systemd 提供了许多很好的工具用于查看系统启动情况,也可以控制在系统启动时运行什么。在这篇文章中,我将说明在 Systemd 类发行版中如何关闭一些令人讨厌的进程。

查看开机启动项

在过去,你能很容易通过查看 /etc/init.d 了解到哪些服务进程会在引导时启动。Systemd 以不同的方式展现,你可以使用如下命令罗列允许开机启动的服务进程。

$ systemctl list-unit-files --type=service | grep enabled
accounts-daemon.service                    enabled
anacron-resume.service                     enabled
anacron.service                            enabled
bluetooth.service                          enabled
brltty.service                             enabled
[...]

在此列表顶部,对我来说,蓝牙服务是冗余项,因为在该电脑上我不需要使用蓝牙功能,故无需运行此服务。下面的命令将停止该服务进程,并且使其开机不启动。

$ sudo systemctl stop bluetooth.service
$ sudo systemctl disable bluetooth.service

你可以通过下面命令确定是否操作成功。

$ systemctl status bluetooth.service
 bluetooth.service - Bluetooth service
  Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled; vendor preset: enabled)
  Active: inactive (dead)
    Docs: man:bluetoothd(8)

停用的服务进程仍然能够被另外一个服务进程启动。如果你真的想在任何情况下系统启动时都不启动该进程,无需卸载该它,只需要把它掩盖起来就可以阻止该进程在任何情况下开机启动。

$ sudo systemctl mask bluetooth.service
 Created symlink from /etc/systemd/system/bluetooth.service to /dev/null.

一旦你对禁用该进程启动而没有出现负面作用感到满意,你也可以选择卸载该程序。

通过执行命令可以获得如下服务列表:

$ systemctl list-unit-files --type=service                       
UNIT FILE                                  STATE   
accounts-daemon.service                    enabled
acpid.service                              disabled
alsa-restore.service                       static    
alsa-utils.service                         masked

你不能启用或禁用静态服务,因为静态服务被其他的进程所依赖,并不意味着它们自己运行。

哪些服务能够禁止?

如何知道你需要哪些服务,而哪些又是可以安全地禁用的呢?它总是依赖于你的个性化需求。

这里举例了几个服务进程的作用。许多服务进程都是发行版特定的,所以你应该看看你的发行版文档(比如通过 google 或 StackOverflow)。

  • accounts-daemon.service 是一个潜在的安全风险。它是 AccountsService 的一部分,AccountsService 允许程序获得或操作用户账户信息。我不认为有好的理由能使我允许这样的后台操作,所以我选择 掩盖 mask 该服务进程。
  • avahi-daemon.service 用于零配置网络发现,使电脑超容易发现网络中打印机或其他的主机,我总是禁用它,别漏掉它。
  • brltty.service 提供布莱叶盲文设备支持,例如布莱叶盲文显示器。
  • debug-shell.service 开放了一个巨大的安全漏洞(该服务提供了一个无密码的 root shell ,用于帮助 调试 systemd 问题),除非你正在使用该服务,否则永远不要启动服务。
  • ModemManager.service 该服务是一个被 dbus 激活的守护进程,用于提供移动 宽频 broadband (2G/3G/4G)接口,如果你没有该接口,无论是内置接口,还是通过如蓝牙配对的电话,以及 USB 适配器,那么你也无需该服务。
  • pppd-dns.service 是一个计算机发展的遗物,如果你使用拨号接入互联网的话,保留它,否则你不需要它。
  • rtkit-daemon.service 听起来很可怕,听起来像是 rootkit。 但是你需要该服务,因为它是一个 实时内核调度器 real-time kernel scheduler
  • whoopsie.service 是 Ubuntu 错误报告服务。它用于收集 Ubuntu 系统崩溃报告,并发送报告到 https://daisy.ubuntu.com 。 你可以放心地禁止其启动,或者永久的卸载它。
  • wpa\_supplicant.service 仅在你使用 Wi-Fi 连接时需要。

系统启动时发生了什么?

Systemd 提供了一些命令帮助调试系统开机启动问题。该命令会重演你的系统启动的所有消息。

$ journalctl -b

-- Logs begin at Mon 2016-05-09 06:18:11 PDT,
end at Mon 2016-05-09 10:17:01 PDT. --
May 16 06:18:11 studio systemd-journal[289]:
Runtime journal (/run/log/journal/) is currently using 8.0M.
Maximum allowed usage is set to 157.2M.
Leaving at least 235.9M free (of currently available 1.5G of space).
Enforced usage limit is thus 157.2M.
[...]

通过命令 journalctl -b -1 可以复审前一次启动,journalctl -b -2 可以复审倒数第 2 次启动,以此类推。

该命令会打印出大量的信息,你可能并不关注所有信息,只是关注其中问题相关部分。为此,系统提供了几个过滤器,用于帮助你锁定目标。让我们以进程号为 1 的进程为例,该进程是所有其它进程的父进程。

$ journalctl _PID=1

May 08 06:18:17 studio systemd[1]: Starting LSB: Raise network interfaces....
May 08 06:18:17 studio systemd[1]: Started LSB: Raise network interfaces..
May 08 06:18:17 studio systemd[1]: Reached target System Initialization.
May 08 06:18:17 studio systemd[1]: Started CUPS Scheduler.
May 08 06:18:17 studio systemd[1]: Listening on D-Bus System Message Bus Socket
May 08 06:18:17 studio systemd[1]: Listening on CUPS Scheduler.
[...]

这些打印消息显示了什么被启动,或者是正在尝试启动。

一个最有用的命令工具之一 systemd-analyze blame,用于帮助查看哪个服务进程启动耗时最长。

$ systemd-analyze blame
         8.708s gpu-manager.service
         8.002s NetworkManager-wait-online.service
         5.791s mysql.service
         2.975s dev-sda3.device
         1.810s alsa-restore.service
         1.806s systemd-logind.service
         1.803s irqbalance.service
         1.800s lm-sensors.service
         1.800s grub-common.service

这个特定的例子没有出现任何异常,但是如果存在系统启动瓶颈,则该命令将能发现它。

你也能通过如下资源了解 Systemd 如何工作:


via: https://www.linux.com/learn/cleaning-your-linux-startup-process

作者:David Both 译者:penghuster 校对:wxy

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

你想知道你的钱花在哪里?这个精心设计的电子表格可以一目了然地回答这个问题。

 title=

如果你像大多数人一样,没有一个无底般的银行帐户。你可能需要仔细观察你的每月支出。

有很多方法可以做到这一点,但是最快最简单的方法是使用电子表格。许多人创建一个非常基本的电子表格来完成这项工作,它由两长列组成,总计位于底部。这是可行的,但这有点傻。

我将通过使用 LibreOffice Calc 创建一个更便于细查的(我认为)以及更具视觉吸引力的个人消费电子表格。

你说不用 LibreOffice?没关系。你可以使用 GnumericCalligra SheetsEtherCalc 等电子表格工具使用本文中的信息。

首先列出你的费用

先别费心 LibreOffice 了。坐下来用笔和纸,列出你的每月日常开支。花时间,翻遍你的记录,记下所有的事情,无论它多么渺小。不要担心你花了多少钱。重点放在你把钱花在哪里。

完成之后,将你的费用分组到最有意义的标题下。例如,将你的燃气、电气和水费放在“水电费”下。你也可能想要为我们每个月都会遇到的意外费用,使用一组名为“种种”。

创建电子表格

启动 LibreOffice Calc 并创建一个空的电子表格。在电子表格的顶部留下三个空白行。之后我们会回来。

你把你的费用归类是有原因的:这些组将成为电子表格上的块。我们首先将最重要的花费组(例如 “家庭”)放在电子表格的顶部。

在工作表顶部第四行的第一个单元格中输入该花费组的名称。将它放大(可以是 12 号字体)、加粗使得它显眼。

在该标题下方的行中,添加以下三列:

  • 花费
  • 日期
  • 金额

在“花费”列下的单元格中输入该组内花费的名称。

接下来,选择日期标题下的单元格。单击 Format 菜单,然后选择 Number Format > Date。对“金额”标题下的单元格重复此操作,然后选择 Number Format > Currency

你会看到这样:

 title=

这是一组开支的方式。不要为每个花费组创建新块, 而是复制你创建的内容并将其粘贴到第一个块旁边。我建议一行放三块, 在它们之间有一个空列。

你会看到这样:

 title=

对所有你的花费组做重复操作。

总计所有

查看所有个人费用是一回事,但你也可以一起查看每组费用的总额和所有费用。

我们首先总计每个费用组的金额。你可以让 LibreOffice Calc 自动做这些。高亮显示“金额”列底部的单元格,然后单击 “Formula” 工具栏上的 “Sum” 按钮。

 title=

单击金额列中的第一个单元格,然后将光标拖动到列中的最后一个单元格。然后按下 Enter。

 title=

现在让我们用你顶部留下的两三行空白行做一些事。这就是你所有费用的总和。我建议把它放在那里,这样无论何时你打开文件时它都是可见的。

在表格左上角的其中一个单元格中,输入类似“月总计”。然后,在它旁边的单元格中,输入 =SUM()。这是 LibreOffice Calc 函数,它可以在电子表格中添加特定单元格的值。

不要手动输入要添加的单元格的名称,请按住键盘上的 Ctrl。然后在电子表格上单击你在每组费用中总计的单元格。

完成

你有一张追踪一个月花费的表。拥有单个月花费的电子表格有点浪费。为什么不用它跟踪全年的每月支出呢?

右键单击电子表格底部的选项卡,然后选择 Move or Copy Sheet。在弹出的窗口中,单击 -move to end position-,然后按下 Enter 键。一直重复到你有 12 张表 - 每月一张。以月份重命名表格,然后使用像 Monthly Expenses 2017.ods 这样的描述性名称保存电子表格。

现在设置完成了,你可以使用电子表格了。使用电子表格跟踪你的花费本身不会坚实你的财务基础,但它可以帮助你控制每个月的花费。

(题图: opensource.com)


作者简介:

Scott Nesbitt - 我是一名长期使用自由/开源软件的用户,并为了乐趣和收益写了各种软件。我不会太严肃。你可以在网上这些地方找到我:Twitter、Mastodon、GitHub。


via: https://opensource.com/article/17/8/budget-libreoffice-calc

作者:Scott Nesbitt 译者:geekpi 校对:wxy

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

你有没有问过自己,我应该在哪里运行 OpenShift?答案是任何地方 - 它可以在裸机、虚拟机、私有云或公共云中很好地运行。但是,这里有一些为什么人们正迁移到围绕全栈和资源消耗自动化相关的私有云和公有云的原因。传统的操作系统一直是关于硬件资源的展示和消耗 - 硬件提供资源,应用程序消耗它们,操作系统一直是交通警察。但传统的操作系统一直局限于单机 注1

那么,在原生云的世界里,现在意味着这个概念扩展到包括多个操作系统实例。这就是 OpenStack 和 OpenShift 所在。在原生云世界,虚拟机、存储卷和网段都成为动态配置的构建块。我们从这些构建块构建我们的应用程序。它们通常按小时或分钟付费,并在不再需要时被取消配置。但是,你需要将它们视为应用程序的动态配置能力。 OpenStack 在动态配置能力(展示)方面非常擅长,OpenShift 在动态配置应用程序(消费)方面做的很好,但是我们如何将它们结合在一起来提供一个动态的、高度可编程的多节点操作系统呢?

要理解这个,让我们来看看如果我们在传统的环境中安装 OpenShift 会发生什么 - 想像我们想要为开发者提供动态访问来创建新的应用程序,或者想象我们想要提供业务线,使其能够访问现有应用程序的新副本以满足合同义务。每个应用程序都需要访问持久存储。持久存储不是临时的,在传统的环境中,这通过提交一张工单实现。没关系,我们可以连到 OpenShift,每次需要存储时都会提交一张工单。存储管理员可以登录企业存储阵列并根据需要删除卷,然后将其移回 OpenShift 以满足应用程序。但这将是一个非常慢的手动过程,而且你可能会遇到存储管理员辞职。

在原生云的世界里,我们应该将其视为一个策略驱动的自动化流程。存储管理员变得更加战略性、设置策略、配额和服务级别(银、黄金等),但实际配置变得动态。

动态过程可扩展到多个应用程序 - 这可能是开发者测试的业务线甚至新应用程序。从 10 多个应用程序到 1000 个应用程序,动态配置提供原生云体验。

下面的演示视频展示了动态存储配置如何与 Red Hat OpenStack 平台(Cinder 卷)以及 Red Hat OpenShift 容器平台配合使用,但动态配置并不限于存储。想象一下,随着 OpenShift 的一个实例需要更多的容量、节点自动扩展的环境。想象一下,推送一个敏感的程序更改前,将网段划分为负载测试 OpenShift 的特定实例。这些是你为何需要动态配置 IT 构建块的原因。OpenStack 实际上是以 API 驱动的方式实现的。

OpenShift 和 OpenStack 一起更好地交付应用程序。OpenStack 动态提供资源,而 OpenShift 会动态地消耗它们。它们一起为你所有的容器和虚拟机需求提供灵活的原生云解决方案。

注1:高可用性集群和一些专门的操作系统在一定程度上弥合了这一差距,但在计算中通常是一个边缘情况。


via: https://blog.openshift.com/openshift-on-openstack-delivering-applications-better-together/

作者:SCOTT MCCARTY 译者:geekpi 校对:wxy

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

树莓派,随心所欲。

 title=

我最近在 SVPerl (硅谷 Perl 聚会)谈到在树莓派上运行 Perl 语言的时候,有人问我,“我听说树莓派应该使用 Python ,是这样吗?”。我非常乐意回答他,这是个常见误解。树莓派可以支持任何语言: Python、Perl 和其他树莓派官方软件 Raspbian Linux 初始安装的语言。

看似很厉害,其实很简单。树莓派的创造者英国的计算机科学教授 Eben Upton 曾经说过,树莓派名字中的‘派’(pi),是想为了听起来像 Python,因为他喜欢这门语言。他选择了这门语言作为孩子们的启蒙语言。但是他和他的团队做了一个通用计算机。开源软件没给树莓派任何限制。我们想运行什么就运行什么,全凭自己心意。

我在 SVPerl 和这篇文章中还想讲第二点,就是介绍我的 “PiFlash” 脚本。虽然它是用 Perl 写的,但是不需要你有多了解 Perl 就可以在 Linux 下将树莓派系统自动化烧录到 SD 卡。这样对初学者就比较友好,避免他们在烧录 SD 卡时候,偶然擦除了整个硬盘。即使是高级用户也可以从它的自动化工作中受益,包括我,这也是我开发这个工具的原因。在 Windows 和 Mac 下也有类似的工具,但是树莓派网站没有介绍类似工具给 Linux 用户。不过,现在有了。

开源软件早就有自己造轮子的传统,因为他们总是崇尚“自痒自挠”去解决问题。这种方式在 Eric S 1997 年的论文和 1999 年的书籍《大教堂与集市》中早有提及,它定义了开源软件的方法论。我也是为了满足想我这样的 Linux 用户,所以写了这个脚本。

下载系统镜像

想要开启树莓派之旅,你首先需要为它下载一个操作系统。我们称之为“系统镜像”文件。一旦你把它下载到你的桌面、手提电脑,或者甚至是另一个树莓派中,我就需要写入或者称之为“烧录”进你的 SD卡。详细情况可以看在线文件。手动做这件事情需要一些功底,你要把系统镜像烧录到整个 SD卡,而不是其中一块分区。系统镜像必须独自包含至少一个分区,因为树莓派引导需要一个 FAT32文件系统分区,系统引导这里开始。除了引导分区,其他分区可以是操作系统内核支持的任何分区类型。

在大部分树莓派中,我们都运行的是某些使用 Linux 内核的发行版。已经有一系列树莓派中常用的系统镜像你可以下载使用。(当然,没什么能阻止你自己造轮子)

树莓派基金会向新手推荐的是“NOOBS”系统。它代表了 “New Out of the Box System”(新鲜出炉即开即用系统),显然它好像听起来像术语 “noob"”(小白),通俗点说就是 “newbie”(菜鸟)。NOOBS 是一个基于树莓派的 Linux 系统,它会给你一个菜单可以在你的树莓派上自动下载安装几个其它的系统镜像。

Raspbian Linux 是 Debian Linux 发行版的树莓派定制版。它是为树莓派开发的正式 Linux 发行版,并且由树莓派基金会维护。几乎所有树莓派驱动和软件都会在 Raspbian 上先试用,然后才会放到其它发行版上。其默认安装博客 Perl。

Ubuntu Linux (还有其社区版的 Ubuntu MATE)也将树莓派作为其支持 ARM (Advanced RISC Machines)处理器的平台之一。RISC(Reduced Instruction Set Computer)Ubuntu 是一个 Debian Linux 的商业化支持的开源分支,它也使用 DEB 包管理器。Perl 也在其中。它仅仅支持 32 位 ARM7 或者 64 位 ARM8 处理器的树莓派 2 和 3。ARM6 的树莓派 1 和 Zero 从未被 Ubuntu 构建过程支持。

Fedora Linux 支持树莓派2 ,而 Fedora 25 支持 3。 Fedora 是一个隶属于红帽(Red Hat)的开源项目。Fedora 是个基础,商业版的 RHEL(Red Hat Enterprise Linux)在其上增加了商业软件包和支持,所以其软件像所有的兼容红帽的发行版一样来自 RPM(Red Hat Package Manager) 软件包。就像其它发行版一样,也包括 Perl。

RISC OS 是一个特别针对 ARM 处理器的单用户操作系统。如果你想要一个比 Linux 系统更加简洁的小型桌面(功能更少),你可以考虑一下。它同样支持 Perl。

RaspBSD 是一个 FreeBSD 的树莓派发行版。它是一个基于 Unix 的系统,而不是 Linux。作为开源 Unix 的一员,它延续了 Unix 的功能,而且和 Linux 有着众多相似之处。包括有类似的开源软件带来的相似的系统环境,包括 Perl。

OSMC,即开源多媒体中心,以及 LibreElec 电视娱乐中心,它们都基于运行 Linux 内核之上的 Kodi 娱乐中心。它是一个小巧、特化的 Linux 系统,所以不要期望它能支持 Perl。

Microsoft Windows IoT Core 是仅运行在树莓派3上的新成员。你需要微软开发者身份才能下载。而作为一个 Linux 极客,我根本不看它。我的 PiFlash 脚本还不支持它,但如果你找的是它,你可以去看看。

PiFlash 脚本

如果你想看看树莓派 SD 卡烧录指导,你可以找到在 Windows 或者 Mac 系统下需要下载的工具来完成烧录任务。但是对于 Linux 系统,只有一系列手工操作建议。我已经手工做过这个太多次,这很容易引发一个开发者的本能去自动化这个过程,这就是 PiFlash 脚本的起源。这有点难,因为 Linux 有太多方法可以配置,但是它们都是基于 Linux 内核的。

我总是觉得,手工操作潜在最大的失误恐怕就是偶然错误地擦除了某个设备,而不是擦除了 SD 卡,然后彻底清除了我本想保留在硬盘的东西。我在 SVPerl 演讲中也说了,我很惊讶地发现在听众中有犯了这种错误(而且不害怕承认)的人。因此,PiFlash 其中一个目的就是保护新手的安全,不会擦除 SD 卡之外的设备。PiFlash 脚本还会拒绝覆写包含了已经挂载的文件系统的设备。

对于有经验的用户,包括我,PiFlash 脚本还提供提供一个简便的自动化服务。下载完系统镜像之后,我不需要必须从 zip格式中解压缩或者提取出系统镜像。PiFlash 可以直接提取它,不管是哪种格式,并且直接烧录到 SD 卡中。

我把 PiFlash 及其指导发布在了 GitHub 上。

命令行用法如下:

piflash [--verbose] input-file output-device
piflash [--verbose] --SDsearch

input-file 参数是你要写入的系统镜像文件,只要是你从树莓派发行版网站下载的镜像都行。output-device 参数是你要写入的 SD 卡的块设备路径。

你也可以使用 --SDsearch 参数列出挂载在系统中 SD 卡设备名称。

可选项 --verbose 可以输出所有的程序状态数据,它在你需要帮助时或者递送 bug 报告和自行排错时很有用。它就是我开发时用的。

下面的例子是我使用该脚本写入仍是 zip 存档的 Raspbian 镜像到位于 /dev/mmcblk0 的 SD 卡:

piflash 2016-11-25-raspbian-jessie.img.zip /dev/mmcblk0

如果你已经指定了 /dev/mmcblk0p1 (SD 卡的第一分区),它会识别到这个分区不是一个正确的位置,并拒绝写入。

在不同的 Linux 系统中怎样去识别哪个设备是 SD 卡是一个技术活。像 mmcblk0 这种在我的笔记本上是基于 PCI 的 SD卡接口。如果我使用了 USB SD 卡接口,它就是 /dev/sdb,这在多硬盘的系统中不好区分。然而,只有少量的 Linux 块设备支持 SD 卡。PiFlash 在这两种情况下都会检查块设备的参数。如果全部失败,它会认为可写入、可移动的,并有着正确物理扇区数量的 USB 驱动器是 SD 卡。

我想这应该能涵盖大部分情况。但是,如果你使用了我不知道的 SD 卡接口呢?我乐意看到你的来信。请在输出信息中加上 --verbos --SDsearch 参数,以便让我可以知道你系统目前的环境。理想情况下,如果 PiFlash 脚本可以被广泛利用,我们可以构建一个开源社区去尽可能的帮助更多的树莓派用户。

树莓派的 CPAN 模块

CPAN(Comprehensive Perl Archive Network)是一个世界范围内包含各种 Perl 模块的的下载镜像。它们都是开源的。大量 CPAN 中的模块都是历久弥坚。对于成千上百的任务,你不需要重复造轮子,只要利用别人已经发布的代码就可以了。然后,你还可以提交你的新功能。

尽管树莓派是个五脏俱全的 Linux 系统,支持大部分 CPAN 模块,但是这里我想强调一下专为树莓派硬件开发的东西。一般来说它们都用在测量、控制、机器人方面的嵌入式系统中。你可以通过 GPIO (General-Purpose Input/Output)针脚将你的树莓派连接到外部电子设备。

可以使用树莓派 GPIO 针脚的模块如下:Device::SMBusDevice::I2CRpi::PIGPIORpi::SPIRpi::WiringPiDevice::WebIO::RaspberryPIDevice::PiGlow。树莓派支持的嵌入式模块如下:UAV::Pilot::Wumpus::Server::Backend::RaspberryPiI2CRPI::DHT11(温度/湿度)、RPI::HCSR04(超声波)、App::RPI::EnvUIRPi::DigiPot::MCP4XXXXRPI::ADC::ADSDevice::PaPiRusDevice::BCM2835::Timer

例子

这里有些我们在树莓派上可以用 Perl 做的事情的例子。

例一:在 OSMC 使用 PiFlash 播放视频

本例中,你将练习如何设置并运行使用 OSMC 操作系统的树莓派。

  • RaspberryPi.Org 下载区,下载最新的 OSMC 版本。
  • 将空 SD 卡插入你的 Linux 电脑或者笔记本。树莓派第一代是全尺寸的 SD 卡,除此以外都在使用 microSD,你也许需要一个通用适配器才能插入它。
  • 在插入前后分别运行 cat /proc/partitions 命令来看看系统分给硬件的设备名称。它可能像这样 /dev/mmcblk0 或者 /dev/sdb, 用如下命令将正确的系统镜像烧录到 SD 卡:piflash OSMC_TGT_rbp2_20170210.img.gz /dev/mmcblk0
  • 弹出 SD 卡,将它插入树莓派中,接上 HDMI 显示器,开机。
  • 当 OSMC 设置完毕,插入一个 USB 设备,在里面放点视频。出于示范目的,我将使用 youtube-dl 程序下载两个视频。运行 youtube-dl OHF2xDrq8dY (彭博关于英国高新产业,包括树莓派的介绍)还有 youtube-dl nAvZMgXbE9c (CNet 发表的“排名前五的树莓派项目”) 。将它们下载到 USB 中,然后卸载移除设备。
  • 将 USB 设备插入到 OSMC 树莓派。点击视频选项进入到外部设备。
  • 只要你能在树莓派中播放视频,那么恭喜你,你已经完成了本次练习。玩的愉快。

例二:随机播放目录中的视频的脚本

这个例子将使用一个脚本在树莓派上的目录中乱序播放视频。根据视频的不同和设备的摆放位置,这可以用作信息亭显示的用途。我写这个脚本用来展示室内体验视频。

  • 设置树莓派引导 Raspbian Linux。连接到 HDMI 监视器。
  • 从 GitHub 上下载 do-video 脚本。把它放到树莓派中。
  • 跟随该页面的安装指导。最主要的事情就是安装 omxplayer 包,它可以使用树莓派硬件视频加速功能平滑地播放视频。
  • 在家目录的 Videos 目录下放一些视频。
  • 运行 do-video ,这样,应该就可以播放视频了

例三:读取 GPS 数据的脚本

这个例子更加深入,更有针对性。它展示了 Perl 怎么从外部设备中读取数据。在先前例子中出现的我的 GitHub上 “Perl on Pi” 有一个 gps-read.pl 脚本。它可以通过一系列端口从 GPS 读取 NMEA(国家海洋电子协会)的数据。页面还有教程,包括构建它所使用的 AdaFruit Industries 部分,但是你可以使用任何能输出 NMEA 数据的 GPS。

通过这些任务,我想你应该可以在树莓派上像使用其他语言一样使用 Perl了。希望你喜欢。


作者简介:

Ian Kluft - 上学开始,Ian 就对喜欢编程和飞行。他一直致力于 Unix 的工作。在 Linux 内核发布后的六个月他转向了 Linux。他有计算机科学硕士学位,并且拥有 CSSLP 资格证(认证规范开发流程专家),另一方面,他还是引航员和认证的飞机指令长。作为一个超过二十五年的认证的无线电爱好者,在近些年,他在一些电子设备上陆续做了实验,包括树莓派。


via: https://opensource.com/article/17/3/perl-raspberry-pi

作者:Ian Kluft 译者:Taylor1024 校对:wxy

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

内核是任何 Linux 机器的核心

之前我已经讲了获取与安装 Ubuntu Linux,这次我将讲桌面和服务器的安装。两类安装都满足某些需求。不同的安装包是从 Ubuntu 分开下载的。你可以从 Ubuntu.com/downloads 选择你需要的。

无论安装类型如何,都有一些相似之处。

可以从桌面系统图形用户界面或从服务器系统命令行添加安装包。

两者都使用相同的内核和包管理器系统。软件包管理器系统是预编译为可在几乎任何 Ubuntu 系统运行的程序的仓库。程序分组成包,然后以安装包进行安装。安装包可以从桌面系统图形用户界面或从服务器系统命令行添加。

程序安装使用一个名为 apt-get 的程序。这是一个包管理器系统或程序管理器系统。最终用户只需输入命令行 apt-get install (package-name),Ubuntu 就会自动获取软件包并进行安装。

软件包通常安装可以通过手册页访问的文档的命令(这本身就是一个主题)。它们可以通过输入 man (command) 来访问。这将打开一个描述该命令详细用法的页面。终端用户还可以 Google 任何的 Linux 命令或安装包,并找到大量关于它的信息。

例如,在安装网络连接存储套件后,可以通过命令行、GUI 或使用名为 Webmin 的程序进行管理。Webmin 安装了一个基于 Web 的管理界面,用于配置大多数 Linux 软件包,它受到了仅安装服务器版本的人群的欢迎,因为它安装为网页,不需要 GUI。它还允许远程管理服务器。

大多数(如果不是全部)基于 Linux 的软件包都有专门帮助你如何运行该软件包的视频和网页。只需在 YouTube 上搜索 “Linux Ubuntu NAS”,你就会找到一个指导你如何设置和配置此服务的视频。还有专门指导 Webmin 的设置和操作的视频。

内核是任何 Linux 安装的核心。由于内核是模块化的,它是非常小的(顾名思义)。我在一个 32MB 的小型闪存上运行 Linux 服务器。我没有打错 - 32MB 的空间!Linux 系统使用的大部分空间都是由安装的软件包使用的。

服务器

服务器安装 ISO 镜像是 Ubuntu 提供的最小的下载。它是针对服务器操作优化的操作系统的精简版本。此版本没有 GUI。默认情况下,它完全从命令行运行。

移除 GUI 和其他组件可简化系统并最大限度地提高性能。最初没有安装的必要软件包可以稍后通过命令行程序包管理器添加。由于没有 GUI,因此必须从命令行完成所有配置、故障排除和包管理。许多管理员将使用服务器安装来获取一个干净或最小的系统,然后只添加他们需要的某些包。这包括添加桌面 GUI 系统并制作精简桌面系统。

广播电台可以使用 Linux 服务器作为 Apache Web 服务器或数据库服务器。这些是真实需要消耗处理能力的程序,这就是为什么它们通常使用服务器形式安装以及没有 GUI 的原因。SNORT 和 Cacti 是可以在你的 Linux 服务器上运行的其他程序(这两个应用程序都在上一篇文章中介绍,可以在这里找到:http://tinyurl.com/yd8dyegu)。

桌面

桌面安装 ISO 镜像相当大,并且有多个在服务器安装 ISO 镜像上没有的软件包。此安装用于工作站或日常桌面使用。此安装类型允许自定义安装包(程序),或者可以选择默认的桌面配置。

桌面安装 ISO 镜像相当大,并且有多个在服务器安装 ISO 镜像上没有的软件包。此安装包专为工作站或日常桌面使用设计。

软件包通过 apt-get 包管理器系统安装,就像服务器安装一样。两者之间的区别在于,在桌面安装中,apt-get 包管理器具有不错的 GUI 前端。这允许通过点击鼠标轻松地从系统安装或删除软件包!桌面安装将设置一个 GUI 以及许多与桌面操作系统相关的软件包。

通过 apt-get 包管理器系统安装软件包,就像服务器安装一样。两者之间的区别在于,在桌面安装中,apt-get 包管理器具有不错的 GUI 前端。*

这个系统安装后随时可用,可以很好的替代你的 Windows 或 Mac 台式机。它有很多包,包括 Office 套件和 Web 浏览器。

Linux 是一个成熟而强大的操作系统。无论哪种安装类型,它都可以配置为适合几乎所有需要。从功能强大的数据库服务器到用于网页浏览和写信给奶奶的基本台式机操作系统,天空有极限,而可用的安装包几乎是不竭的。如果你遇到一个需要计算机化解决方案的问题,Linux 可能会提供免费或低成本的软件来解决该问题。

通过提供两个安装版本,Ubuntu 做得很好,这让人们开始朝着正确的方向前进。

Cottingham 是前无线电总工程师,现在从事流媒体工作。


via: http://www.radiomagonline.com/deep-dig/0005/linux-installation-types-server-vs-desktop/39123

作者:Chris Cottingham 译者:geekpi 校对:wxy

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

探索 哈希表 hash table 的世界并理解其底层的机制是非常有趣的,并且将会受益匪浅。所以,让我们了解它,并从头开始探索吧。

哈希表是许多现代软件应用程序中一种常见的数据结构。它提供了类似字典的功能,使你能够在其中执行插入、删除和删除等操作。这么说吧,比如我想找出“苹果”的定义是什么,并且我知道该定义被存储在了我定义的哈希表中。我将查询我的哈希表来得到定义。它在哈希表内的记录看起来可能像:"苹果" => "一种拥有水果之王之称的绿色水果"。这里,“苹果”是我的关键字,而“一种拥有水果之王之称的水果”是与之关联的值。

还有一个例子可以让我们更清楚,哈希表的内容如下:

"面包" => "固体"
"水" => "液体"
"汤" => "液体"
"玉米片" => "固体"

我想知道面包是固体还是液体,所以我将查询哈希表来获取与之相关的值,该哈希表将返回“固体”给我。现在,我们大致了解了哈希表是如何工作的。使用哈希表需要注意的另一个重要概念是每一个关键字都是唯一的。如果到了明天,我拥有一个面包奶昔(它是液体),那么我们需要更新哈希表,把“固体”改为“液体”来反映哈希表的改变。所以,我们需要添加一条记录到字典中:关键字为“面包”,对应的值为“液体”。你能发现下面的表发生了什么变化吗?(LCTT 译注:不知道这个“面包奶昔”是一种什么食物,大约是一种面包做的奶昔,总之你就理解成作者把液体的“面包奶昔”当成一种面包吧。)

"面包" => "液体"
"水" => "液体"
"汤" => "液体"
"玉米片" => "固体"

没错,“面包”对应的值被更新为了“液体”。

关键字是唯一的,我的面包不能既是液体又是固体。但是,是什么使得该数据结构与其他数据结构相比如此特殊呢?为什么不使用一个数组来代替呢?它取决于问题的本质。对于某一个特定的问题,使用数组来描述可能会更好,因此,我们需要注意的关键点就是,我们应该选择最适合问题的数据结构。例如,如果你需要做的只是存储一个简单的杂货列表,那么使用数组会很适合。考虑下面的两个问题,两个问题的本质完全不同。

  1. 我需要一个水果的列表
  2. 我需要一个水果的列表以及各种水果的价格(每千克)

正如你在下面所看到的,用数组来存储水果的列表可能是更好的选择。但是,用哈希表来存储每一种水果的价格看起来是更好的选择。

//示例数组
["苹果", "桔子", "梨子", "葡萄"]   
//示例哈希表  
{ "苹果" : 3.05,
  "桔子" : 5.5,
  "梨子" : 8.4,
  "葡萄" : 12.4  
}

实际上,有许多的机会需要使用哈希表。

时间以及它对你的意义

这里有篇对时间复杂度和空间复杂度的一个复习

平均情况下,在哈希表中进行搜索、插入和删除记录的时间复杂度均为 O(1) 。实际上,O(1) 读作“大 O 1”,表示常数时间。这意味着执行每一种操作的运行时间不依赖于数据集中数据的数量。我可以保证,查找、插入和删除项目均只花费常数时间,“当且仅当”哈希表的实现方式正确时。如果实现不正确,可能需要花费很慢的 O(n) 时间,尤其是当所有的数据都映射到了哈希表中的同一位置/点。

构建一个好的哈希表

到目前为止,我们已经知道如何使用哈希表了,但是如果我们想构建一个哈希表呢?本质上我们需要做的就是把一个字符串(比如 “狗”)映射到一个哈希代码(一个生成的数),即映射到一个数组的索引。你可能会问,为什么不直接使用索引呢?为什么要这么麻烦呢?因为通过这种方式我们可以直接查询 “狗” 并立即得到 “狗” 所在的位置,String name = Array["狗"] // 名字叫拉斯。而使用索引查询名称时,可能出现的情况是我们不知道名称所在的索引。比如,String name = Array[10] // 该名字现在叫鲍勃 - 那不是我的狗的名字。这就是把一个字符串映射到一个哈希代码的益处(对应于一个数组的索引而言)。我们可以通过使用模运算符和哈希表的大小来计算出数组的索引:index = hash_code % table_size

我们需要避免的另一种情况是两个关键字映射到同一个索引,这叫做哈希碰撞,如果哈希函数实现的不好,这很容易发生。实际上,每一个输入比输出多的哈希函数都有可能发生碰撞。通过下面的同一个函数的两个输出来展示一个简单的碰撞:

int cat_idx = hashCode("猫") % table_size; //cat_idx 现在等于 1
int dog_idx = hashCode("狗") % table_size; //dog_idx 也等于 1

我们可以看到,现在两个数组的索引均是 1 。这样将会出现两个值相互覆盖,因为它们被写到了相同的索引中。如果我们查找 “猫” 的值,将会返回 “拉斯” ,但是这并不是我们想要的。有许多可以解决哈希碰撞的方法,但是更受欢迎的一种方法叫做链接。链接的想法就是对于数组的每一个索引位置都有一个链表,如果碰撞发生,值就被存到链表中。因此,在前面的例子中,我们将会得到我们需要的值,但是我们需要搜索数组中索引为 1 的位置上的链表。伴有链接的哈希实现需要 O(1 + α) 时间,其中 α 是装载因子,它可以表示为 n/k,其中 n 是哈希表中的记录数目,k 是哈希表中可用位置的数目。但是请记住,只有当你给出的关键字非常随机时,这一结论才正确(依赖于 SUHA)。

这是做了一个很大的假设,因为总是有可能任何不相等的关键字都散列到同一点。这一问题的一个解决方法是去除哈希表中关键字对随机性的依赖,转而把随机性集中于关键字是如何被散列的,从而减少矛盾发生的可能性。这被称为……

通用散列

这个观念很简单,从 通用散列 universal hash 家族集合随机选择一个哈希函数 h 来计算哈希代码。换句话来说,就是选择任何一个随机的哈希函数来散列关键字。通过这种方法,两个不同的关键字的散列结果相同的可能性将非常低(LCTT 译注:原文是“not be the same”,应是笔误)。我只是简单的提一下,如果不相信我那么请相信数学。实现这一方法时需要注意的另一件事是如果选择了一个不好的通用散列家族,它会把时间和空间复杂度拖到 O(U),其中 U 是散列家族的大小。而其中的挑战就是找到一个不需要太多时间来计算,也不需要太多空间来存储的哈希家族。

上帝哈希函数

追求完美是人的天性。我们是否能够构建一个完美的哈希函数,从而能够把关键字映射到整数集中,并且几乎没有碰撞。好消息是我们能够在一定程度上做到,但是我们的数据必须是静态的(这意味着在一定时间内没有插入/删除/更新)。一个实现完美哈希函数的方法就是使用 2 级哈希 2-Level Hashing ,它基本上是我们前面讨论过的两种方法的组合。它使用通用散列来选择使用哪个哈希函数,然后通过链接组合起来,但是这次不是使用链表数据结构,而是使用另一个哈希表。让我们看一看下面它是怎么实现的:

 title=

但是这是如何工作的以及我们如何能够确保无需关心碰撞?

它的工作方式与生日悖论相反。它指出,在随机选择的一堆人中,会有一些人生日相同。但是如果一年中的天数远远大于人数(平方以上),那么有极大的可能性所有人的生日都不相同。所以这二者是如何相关的?对于每一个链接哈希表,其大小均为第一级哈希表大小的平方。那就是说,如果有两个元素被散列到同一个点,那么链接哈希表的大小将为 4 。大多数时候,链接哈希表将会非常稀疏/空。

重复下面两步来确保无需担心碰撞:

  • 从通用散列家族中选择一个哈希函数来计算
  • 如果发生碰撞,那么继续从通用散列家族中选择另一个哈希函数来计算

字面上看就是这样(这是一个 O(n^2) 空间的解)。如果需要考虑空间问题,那么显然需要另一个不同的方法。但是值得庆幸的是,该过程平均只需要进行两次

总结

只有具有一个好的哈希函数才能算得上是一个好的哈希表。在同时保证功能实现、时间和空间的提前下构建一个完美的哈希函数是一件很困难的事。我推荐你在解决问题的时候首先考虑哈希表,因为它能够为你提供巨大的性能优势,而且它能够对应用程序的可用性产生显著差异。哈希表和完美哈希函数常被用于实时编程应用中,并且在各种算法中都得到了广泛应用。你见或者不见,哈希表就在这儿。


via: http://www.zeroequalsfalse.press/2017/02/20/hashtables/

作者:Marty Jacobs 译者:ucasFL 校对:wxy

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