Linux 性能监控、测试、优化工具

Linux 平台上的性能工具有很多,眼花缭乱,长期的摸索和经验发现最好用的还是那些久经考验的、简单的小工具。系统性能专家 Brendan D. Gregg 在最近的 LinuxCon NA 2014 大会上更新了他那个有名的关于 Linux 性能方面的 talk (Linux Performance Tools) 和幻灯片。

和 Brendan 去年的 talk 比较,今年增加了测试和优化两部分。下面的三张图片分别总结了 Linux 各个子系统以及监控、测试、优化这些子系统所用到的工具。

监控

linux performance tools

测试

linux performance tools

优化

linux performance tools

推荐几本 Unix/Linux 经典书

几天前答应过一位新 VPS 客户,推荐一点 Linux 书,今天静下来写文才发现推荐书其实不是这么容易,至少应该知道一点读书人的背景,是入门、进阶还是高级,阅读习惯啊、方式啊;有人喜欢看例子书,边看边操作学得快;有的人喜欢先读原理,后操作。

现在每年增加的信息量比过去几百年还要多,不过好书还是那么少,经过历史考验的经典书就更少了,每个领域的经典书就那么几本,作为初学者应该首先看完该领域的经典书,然后再看其他的流行好书。

选择经典书是因为,我们实在没有时间花在烂书上,好书能更快更好的帮助我们理解内容,好书是一种享受,你不会觉得读书是一种辛苦。选择英文书是因为,这些经典书的英文都写得朴实、简单,不超过大学四级的阅读水平,长时间侵淫英文书可以为自己以后学习和工作打好基础。在工作中,最新最好最权威的资料都是英文的,翻译过来的二手资料不放心,做技术这行迟早要用英语混日子~

下面是 vpsee 看过的一些好书,有些书至今还放在桌头翻阅,这些经典不管怎么过分推荐和转载都不过分。

Linux 入门

Running LinuxLinux in a Nutshell 都是很棒的 Linux 入门书,如果你是计算机专业出身,只需要这两本书就可以了,这两本书都包括一些初级系统管理内容,Linux in a Nutshell 稍微难一点,建议阅读顺序是先 Running Linux 后 Linux in a Nutshell.

系统管理和网络

UNIX System Administration Handbook 可能是系统管理方面最权威的的一本大部头百科全书式著作,第一版本是1989年发行的,以后一直是 Unix 系统管理的方面的经典,其作者在2002年发布了对应的 Linux Administration Handbook 第一版,然后又成了 Linux 系统管理的必读,终于在2010年的时候作者把这两本书合为一本 UNIX and Linux System Administration Handbook.

Essential System Administration 是另一个 Unix/Linux 系统管理的经典书,可以替代 UNIX and Linux System Administration Handbook,不过建议两本都看看。

TCP/IP Illustrated, Volume 1: The Protocols 是理解 TCP/IP 协议的必读经典,书的内容不涉及具体的网络管理命令,也不讨论如何架设各种服务器,主要讨论 TCP/IP 各层协议是如何工作的,不管你是 System Administrator, Network Administrator, DevOps 还是 System Programmer 这本书都必读,就算今天用 Django, Ruby on Rails 之类的框架编程也应该了解一下底层 HTTP 协议是如何工作的,网络包是如何一层一层的封装、解封的。TCP/IP Illustrated 三部曲的另外两本也很经典,不过太窄太具体,除非你是 TCP/IP 协议设计者或网络栈码农,看 TCP/IP Illustrated, Volume 2: The Implementation 的用处不是很大。

系统编程

The UNIX Programming Environment 是两位 UNIX 大师 Brian W. Kernighan 和 Rob Pike 的合著,UNIX/Linux 编程入门的最好读物,字里行间里浸透了 UNIX 的哲学和设计思想。

The C Programming Language 可能有人会问为啥学 Unix/Linux 要懂 C 语言,C 是 Unix/Linux 的核心,想继续深入理解 Unix/Linux 必须懂点 C 语言,不然下面一些书没法继续读,C 语言还是一种优美、高效的语言,每个程序员都应该会(个人观点)。

Advanced Programming in the Unix Environment 是 Unix/Linux 编程的经典必读书,Unix 大师级作者 Richard Stevens 的巨著,事实上 Richard Stevens 的每本书都是巨著。

Unix Network Programming 是 Richard Stevens 另一巨著,这本经典 Unix 网络编程书可看作上面那本的补充。

编程还应该包括 shell 编程,这里没有单独拿出来推荐是因为因为上面推荐的入门和系统管理书里面都或多或少包括了一些 shell 编程基础知识。

操作系统原理和内核

Operating Systems: Design and Implementation 是操作系统原理的经典书,讲系统原理的还有另一本经典恐龙书 Operating System Concepts,我个人更喜欢前一本一些,理论加实践,书的作者在大学教书的时候没能找到满意的操作系统来教学自己写了一个 Minix,Linus Torvalds 发现 Minix 太简单不实用自己写了一个 Linux,貌似牛人都有共同的特点,不满意就自己造一个~,修改 Minix 内核是很有趣的事情,换工作后一直没机会再玩 Minix.

Linux Device Drivers 是内核编程的入门读物,难得这本经典书还是免费的。

Understanding the Linux Kernel 是 Linux 内核方面的经典,看这本书之前最好看过一些上面讲操作系统原理的书,不要指望看一遍就把这本书都搞懂,理解内核难点的地方在于内核之间的子系统是独立又是交叉的,又缺少实际可运行可修改的例子,不像 web 编程,改几行代码就可以立刻看到效果,所以内核学习是个痛苦的过程,这本书有助于建立一幅完整的 Linux 内核图景。

安装和使用 Elasticsearch

Elasticsearch 是开源搜索平台的新成员,实时数据分析的神器,发展迅猛,基于 Lucene、RESTful、分布式、面向云计算设计、实时搜索、全文搜索、稳定、高可靠、可扩展、安装+使用方便,介绍都说的很好听,好不好用拿出来遛一遛。

做了个简单测试,在两台完全一样的虚拟机上,2000万条左右数据,Elasticsearch 插入数据速度比 MongoDB 慢很多(可以忍受),但是搜索/查询速度快10倍以上,这只是单机情况,多机集群情况下 Elasticsearch 表现更好一些。以下安装步骤在 Ubuntu Server 14.04 LTS 上完成。

安装 Elasticsearch

升级系统后安装 Oracle Java 7,既然 Elasticsearch 官方推荐使用 Oracle JDK 7 就不要尝试 JDK 8 和 OpenJDK 了:

$ sudo apt-get update
$ sudo apt-get upgrade

$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update

$ sudo apt-get install oracle-java7-installer

加入 Elasticsearch 官方源后安装 elasticsearch:

$ wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | sudo apt-key add -
$ sudo echo "deb http://packages.elasticsearch.org/elasticsearch/1.1/debian stable main" >> /etc/apt/sources.list

$ sudo apt-get update
$ sudo apt-get install elasticsearch

加入到系统启动文件并启动 elasticsearch 服务,用 curl 测试一下安装是否成功:

$ sudo update-rc.d elasticsearch defaults 95 1

$ sudo /etc/init.d/elasticsearch start

$ curl -X GET 'http://localhost:9200'
{
  "status" : 200,
  "name" : "Fer-de-Lance",
  "version" : {
    "number" : "1.1.1",
    "build_hash" : "f1585f096d3f3985e73456debdc1a0745f512bbc",
    "build_timestamp" : "2014-04-16T14:27:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.7"
  },
  "tagline" : "You Know, for Search"
}

Elasticsearch 的集群和数据管理界面 Marvel 非常赞,可惜只对开发环境免费,如果这个工具也免费就无敌了,安装很简单,完成后重启服务访问 http://192.168.2.172:9200/_plugin/marvel/ 就可以看到界面:

$ sudo /usr/share/elasticsearch/bin/plugin -i elasticsearch/marvel/latest

$ sudo /etc/init.d/elasticsearch restart
 * Stopping Elasticsearch Server                                           [ OK ]
 * Starting Elasticsearch Server                                           [ OK ]

Elasticsearch Marvel

安装 Python 客户端驱动

和 MongoDB 一样,我们一般用程序和 Elasticsearch 交互,Elasticsearch 也支持多种语言的客户端驱动,这里仅安装 Python 驱动,其他语言可以参考官方文档。

$ sudo apt-get install python-pip
$ sudo pip install elasticsearch

写个简单程序把 gene_info.txt 的数据导入到 Elasticsearch:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, os.path, sys, re
import csv, time, string
from datetime import datetime
from elasticsearch import Elasticsearch

def import_to_db():
    data = csv.reader(open('gene_info.txt', 'rb'), delimiter='\t')
    data.next()

    es = Elasticsearch()
    for row in data:
        doc = {
            'tax_id': row[0],
            'GeneID': row[1],
            'Symbol': row[2],
            'LocusTag': row[3],
            'Synonyms': row[4],
            'dbXrefs': row[5],
            'chromosome': row[6],
            'map_location': row[7],
            'description': row[8],
            'type_of_gene': row[9],
            'Symbol_from_nomenclature_authority': row[10],
            'Full_name_from_nomenclature_authority': row[11],
            'Nomenclature_status': row[12],
            'Other_designations': row[13],
            'Modification_date': row[14]
        }
        res = es.index(index="gene", doc_type='gene_info', body=doc)

def main():
    import_to_db()

if __name__ == "__main__":
    main()

Kibana 是一个功能强大的数据显示客户端,通过插件方式和 Elasticsearch 集成在一起,安装很容易,下载解压就可以了,然后重启 Elasticsearch 服务访问 http://192.168.2.172:9200/_plugin/kibana/ 就能看到界面:

$ wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.1.tar.gz
$ tar zxvf kibana-3.0.1.tar.gz
$ sudo mv kibana-3.0.1 /usr/share/elasticsearch/plugins/_site
$ sudo /etc/init.d/elasticsearch restart

Elasticsearch Kibana

查看 Linux 系统信息的 web 面板 psdash

psdash 是一款查看 Linux 系统信息的 web 面板,和我们以前提到的另一款系统监控工具 Glances 一样,psDash 的系统信息的采集也是由 psutil 完成的。和 Glances 不同的是,psdash 没有提供 API,只带了一个基于 Flask 的 web 界面,默认每3秒刷新一次数据和界面。

升级系统后安装必要软件包:

$ sudo apt-get update
$ sudo apt-get upgrade

$ sudo apt-get install git gcc python-dev python-setuptools

下载 psdash 源代码后安装:

$ git clone https://github.com/Jahaja/psdash.git
$ cd psdash
$ sudo python setup.py install

启动 psdash:

$ sudo psdash --log /var/log/psdash.log --log /var/log/mydb.log

打开浏览器访问 http://192.168.2.99:5000/

psdash

在 Linux 上创建 Software RAID 10

昨天重装一台老服务器的时候发现 Intel hardware RAID 控制卡有问题,不能识别所有硬盘,但是安装操作系统过程中可以识别所有硬盘,还有一个问题就是操作系统安装正常,但是安装完后无法启动,某种原因导致 BIOS 不能从硬盘启动系统。所以打算把操作系统安装到一个 USB 盘上,然后从 USB 盘启动系统,并给上面的6块硬盘做成 Software RAID 10 后挂载到系统里用。

做 Software RAID 不要求硬盘都一模一样,但是强烈推荐用同一厂商、型号和大小的硬盘。为啥 RAID 10,不选 RAID0, RAID1, RAID5 呢?答:RAID0 太危险,RAID1 性能稍逊一些,RAID5 频繁写情况下性能差,RAID10 似乎是当今磁盘阵列的最佳选择,特别适合做 KVM/Xen/VMware 虚拟机母机(host)的本地存储系统(如果不考虑 SAN 和分布式存储的话)。

这台服务器上有6块完全相同的硬盘,给每块硬盘分成一个区,分区格式为 Linux software raid:

# fdisk /dev/sda

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-91201, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-91201, default 91201):
Using default value 91201

Command (m for help): p

Disk /dev/sda: 750.2 GB, 750156374016 bytes
255 heads, 63 sectors/track, 91201 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0005c259

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1       91201   732572001   83  Linux

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

按照上面的 /dev/sda 的分区例子依次给剩下的5块硬盘 sdc, sdd, sde, sdf, sdg 分区、更改分区格式:

# fdisk /dev/sdc
...
# fdisk /dev/sdd
...
# fdisk /dev/sde
...
# fdisk /dev/sdf
...
# fdisk /dev/sdg
...

分区完成后就可以开始创建 RAID 了,在上面的6个相同大小的分区上创建 raid10:

# mdadm --create /dev/md0 -v --raid-devices=6 --level=raid10 /dev/sda1 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1 /dev/sdg1
mdadm: layout defaults to n2
mdadm: layout defaults to n2
mdadm: chunk size defaults to 512K
mdadm: size set to 732440576K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

查看磁盘阵列的初始化过程(build),根据磁盘大小和速度,整个过程大概需要几个小时:

# watch cat /proc/mdstat
Every 2.0s: cat /proc/mdstat                                       Tue Feb 11 12:51:25 2014

Personalities : [raid10]
md0 : active raid10 sdg1[5] sdf1[4] sde1[3] sdd1[2] sdc1[1] sda1[0]
      2197321728 blocks super 1.2 512K chunks 2 near-copies [6/6] [UUUUUU]
      [>....................]  resync =  0.2% (5826816/2197321728) finish=278.9min speed=13
0948K/sec

unused devices: 

等阵列完成初始化后,就可以给 md0 设备创建分区和文件系统了,有了文件系统就可以挂载到系统里:

# fdisk /dev/md0
# mkfs.ext4 /dev/md0p1

# mkdir /raid10
# mount /dev/md0p1 /raid10

修改 /etc/fstab 文件让每次系统启动时自动挂载:

# vi /etc/fstab
...
/dev/md0p1 /raid10 ext4 noatime,rw 0 0

在上面的 /etc/fstab 文件里使用 /dev/md0p1 设备名不是一个好办法,因为 udev 的缘故,这个设备名常在重启系统后变化,所以最好用 UUID,使用 blkid 命令找到相应分区的 UUID:

# blkid
...
/dev/md0p1: UUID="093e0605-1fa2-4279-99b2-746c70b78f1b" TYPE="ext4"

然后修改相应的 fstab,使用 UUID 挂载:

# vi /etc/fstab
...
#/dev/md0p1 /raid10 ext4 noatime,rw 0 0
UUID=093e0605-1fa2-4279-99b2-746c70b78f1b /raid10 ext4 noatime,rw 0 0

查看 RAID 的情况:

# mdadm --query --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Tue Feb 11 12:50:38 2014
     Raid Level : raid10
     Array Size : 2197321728 (2095.53 GiB 2250.06 GB)
  Used Dev Size : 732440576 (698.51 GiB 750.02 GB)
   Raid Devices : 6
  Total Devices : 6
    Persistence : Superblock is persistent

    Update Time : Tue Feb 11 18:48:10 2014
          State : clean
 Active Devices : 6
Working Devices : 6
 Failed Devices : 0
  Spare Devices : 0

         Layout : near=2
     Chunk Size : 512K

           Name : local:0  (local to host local)
           UUID : e3044b6c:5ab972ea:8e742b70:3f766a11
         Events : 70

    Number   Major   Minor   RaidDevice State
       0       8        1        0      active sync   /dev/sda1
       1       8       33        1      active sync   /dev/sdc1
       2       8       49        2      active sync   /dev/sdd1
       3       8       65        3      active sync   /dev/sde1
       4       8       81        4      active sync   /dev/sdf1
       5       8       97        5      active sync   /dev/sdg1

误删大文件的一个可能解救办法

上周在一台 OpenNebula 服务器上操作虚拟机镜像,正在生成和比对镜像文件的 md5 指纹:

# ls -l test.img
-rw-r--r-- 1 root root 10486808576 Oct 12 02:21 test.img

# md5sum test.img

在另一个窗口清理文件的时候不小心误删了这个 10GB 左右的镜像文件:

# rm test.img

这时候行动迅速的话还有时间拯救,因为服务器繁忙,执行 rm 删除 10GB 大文件的时候需要一点时间,利用这点时间切换到另一窗口使用 Ctrl+Z 立刻暂停 md5sum:

[1]+  Stopped                 md5sum test.img

这里利用的一个原理就是,如果有其他程序正在使用这个文件的话,Linux 不会真正删除这个文件(即使执行了 rm 命令)。我们在删除命令 rm 执行完之前暂停 md5sum,这样 test.img 就一直会被 md5um 占用而不会真正被 rm 删除。

使用 jobs 可以看到被暂停的 md5sum 的进程号 30888,然后查看这个进程打开了哪些文件:

# jobs -l
[1]+ 30888 Stopped                 md5sum test.img

# ls -l /proc/30888/fd
total 0
lrwx------ 1 root root 64 Oct 22 04:04 0 -> /dev/pts/3
lrwx------ 1 root root 64 Oct 22 04:04 1 -> /dev/pts/3
lrwx------ 1 root root 64 Oct 22 04:04 2 -> /dev/pts/3
lr-x------ 1 root root 64 Oct 22 04:04 3 -> /root/test.img (deleted)

使用 cp 就可以把误删的文件拷贝出来:

# cp /proc/30888/fd/3 save.img
# ls -l save.img
-rw-r--r-- 1 root root 10486808576 Oct 22 06:11 save.img

误删文本文件的话可以尝试用 grep 恢复,误删 exe/doc/png/jpg/gif 之类的文件的话,可以用第三方 ext2/ext3 文件恢复工具 TestDisk, PhotoRec 等帮助恢复文件。

使用 lsyncd 同步本地和远程目录

自动同步本地服务器(或 VPS)上的目录到另一台或多台远程服务器的办法和工具有很多,最简单的办法可能是用 rsync + cron(参考:用 VPS 给博客做镜像),这种办法有个问题就是 rsync 只能在固定时间间隔里被 cron 调用,如果时间间隔设的太短,频繁 rsync 会增加服务器负担;如果时间间隔设的太长,可能数据不能及时同步。今天介绍的 lsyncd 采用了 Linux 内核(2.6.13 及以后)里的 inotify 触发机制,这种机制可以做到只有在需要(变化)的时候才去同步。lsyncd 密切监测本地服务器上的参照目录,当发现目录下有文件或目录变更后,立刻通知远程服务器,并通过 rsync 或 rsync+ssh 方式实现文件同步。lsyncd 默认同步触发条件是每20秒或者每积累到1000次写入事件就触发一次,当然,这个触发条件可以通过配置参数调整。

lsyncd 已经在 Ubuntu 的官方源里,安装很容易:

$ sudo apt-get update
$ sudo apt-get install lsyncd

lsyncd 安装后没有自动生成所需要的配置文件和目录,需要手动创建:

$ sudo mkdir /etc/lsyncd
$ sudo touch /etc/lsyncd/lsyncd.conf.lua

$ sudo mkdir /var/log/lsyncd
$ sudo touch /var/log/lsyncd/lsyncd.{log,status}

配置 lsyncd,注意 source, host, targetdir 部分,依次是本地需要同步到远程的目录(源头),远程机器的 IP,远程目录(目标):

$ sudo vi /etc/lsyncd/lsyncd.conf.lua
settings {
        logfile = "/var/log/lsyncd/lsyncd.log",
        statusFile = "/var/log/lsyncd/lsyncd.status"
}

sync {
        default.rsyncssh,
        source = "/home/vpsee/local",
        host = "192.168.2.5",
        targetdir = "/remote"
}

配置本地机器和远程机器 root 帐号无密码 ssh 登陆,并在远程机器上(假设 IP 是 192.168.2.5)创建一个 /remote 目录:

$ sudo su
# ssh-keygen -t rsa
# ssh-copy-id root@192.168.2.5

# ssh 192.168.2.5
# mkdir /remote

配置好后就可以在本地机器上启动 lsyncd 服务了,启动服务后本地机器 /home/vpsee/local 下的目录会自动同步到远程机器的 /remote 目录下:

$ sudo service lsyncd restart

除了同步本地目录到远程目录外,lsyncd 还可以轻松做到同步本地目录到本地另一目录,只要修改配置文件就可以了:

$ sudo vi /etc/lsyncd/lsyncd.conf.lua
settings {
        logfile = "/var/log/lsyncd/lsyncd.log",
        statusFile = "/var/log/lsyncd/lsyncd.status"
}


sync {
	default.rsync,
	source = "/home/vpsee/local",
	target = "/localbackup"
}

$ sudo service lsyncd restart

使用 SysRq 键安全重启挂起的 Linux

最近有台 NFS 服务器挂机,可以 ping 通,但不能 ssh 登陆,也不能通过本地终端登陆,只能重启了。我们一般处理文件服务器这种类型的重启都格外小心,不到迫不得已不会直接硬重启。Linux 运行过程中(为了提高性能)会把大量的数据暂时放在内存缓存中,而不是实时同步写入到磁盘,Linux 根据情况只有在需要(触发某条件)的时候才写入磁盘,所以这个时候挂机,数据还留在内存,没有办法及时写到磁盘,强制断电重启会造成数据不一致、部分数据丢失、文件系统损坏等。

为了在这样的情况下实现安全重启,我们可以利用 SysRq,当然有个条件是,系统虽然罢工停止了对大部分服务的响应,但仍然能处理键盘的中断请求。SysRq (System request) 常被称为 Magic SysRq key,在 Linux 下它被定义为一系列按键组合,之所以说它 magic,是因为它常能在系统挂起、多数服务都无法响应的时候做点事(预定义的操作),而且能在磁盘数据安全的情况下完成重启,除此之外还能捕获一些有用的系统运行信息。

首先确认当前使用的 Linux 内核支持 SysRq:

# grep "CONFIG_MAGIC_SYSRQ" /boot/config-`uname -r`
CONFIG_MAGIC_SYSRQ=y

如果系统默认关闭了 kernel.sysrq 的话,需要打开。为了保证每次系统重启内核参数都生效,建议把配置写到 sysctl.conf 文件里:

# sysctl kernel.sysrq
kernel.sysrq = 0

# sysctl -w kernel.sysrq=1
kernel.sysrq = 1

# vi /etc/sysctl.conf
...
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 1
...

SysRq 配置好后就可以开始用了。SysRq 安全重启的推荐按键组合是 Alt + SysRq + R-E-I-S-U-B,先按下 Alt 键和 SysRq 键,然后依次按下 R E I S U B 键(不区分大小写)。这个 R E I S U B 序列组合的意思是:

R – 把键盘设置为 ASCII 模式
E – 向除 init 外所有进程发送 SIGTERM 信号
I – 向除 init 外所有进程发送 SIGKILL 信号
S – 磁盘缓冲区同步
U – 重新挂载为只读模式
B – 重启系统

需要注意的是这些按键之间有顺序,而且按键之间有时间间隔(因为要等待前一个操作的完成),推荐的时间间隔是 R – 1 秒 – E – 30 秒 – I – 10 秒 – S – 5 秒 – U – 5 秒 – B.

我们通常只在意数据是否安全的同步到了磁盘,所以我们一般只用 S-B 组合,按下 Alt + SysRq + S 后等待 Emergency Sync complete 提示,同步完成确认后用 Alt + SysRq + B 立刻重启。

设计师的 Linux 桌面发行版 elementary OS

很少关注桌面方面的事情,上次玩了一下 CrunchBang Linux 后又点燃了对 Linux 各种版本的好奇。今天介绍的是 elementary OS,号称 “最美的 Linux”. Elementary 最早是 Ubuntu 的一个美化项目,现在成了一个独立的 Linux 桌面发行版 elementary OS(基于 Ubuntu)。

安装完 elementary OS 后登陆界面不错,进去后感觉也挺好,要说 “最美” 可能有人有不同的看法,不过的确是精心设计过的。有点不习惯的是,elementary OS 在默认软件选择上有点非主流,浏览器用的是 Midori,邮件程序用的是 Geary Mail,Terminal 用的是 Pantheon Terminal,文本编辑器用的是 Scratch,音乐播放器使用的是 noise,文件管理器是 Pantheon Files,猜测项目的作者选择这些软件是为了更好的和发行版的风格兼容。貌似自带的大部分软件都是自家写的,比如 Pantheon Terminal, Pantheon Files, noise, Scratch 等就是 elementary Apps team 维护的。

elementary OS 默认桌面:

elementary OS

浏览器和 Terminal:

elementary OS

虽然 elementary OS 的默认软件有点非主流,不过可以很容易通过它自带的 Software Center 安装自己喜欢的软件,当然也可以 apt-get install,甚至连 elementary OS 的源(/etc/apt/sources.list)都是直接用的是 ubuntu 的,更像是一个 Ubuntu 衍生版:

elementary OS

默认带的中文字体发虚,安装一个中文字体:

$ sudo apt-get update
$ sudo apt-get install ttf-wqy-microhei

想安装更多好看的主题的话参考 5 New Awesome Elementary Themes,先安装用来切换主题调整界面的工具 elementary-tweaks,再安装主题本身 elementary-blue-theme:

$ sudo add-apt-repository ppa:versable/elementary-update
$ sudo apt-get update
$ sudo apt-get install elementary-tweaks
$ sudo apt-get install elementary-blue-theme

简单的说,可以把 elementary OS 看成一个简化的、美化的、符合部分人喜好的 Ubuntu,简单归简单,貌似 elementary OS 的目标一点都不简单,为了统一风格、用户体验和精益求精,不惜重复造轮子采用 Vala 语言重新开发一些常用应用软件,有别于那种用第三方软件拼凑起来的发行版,不知道这种模式能坚持多久,这里做个记号,重点关注一下。

如何的退出无响应的 SSH 连接

大家有时候会发现 ssh 挂在那里没有响应了,可能是客户端的问题,也可能是服务器端的问题,也可能是客户端和服务器之间的网络问题;可能是客户端电脑休眠后连接断了、可能是网络断了、可能是 WiFi 信号不好、可能是网络延迟大了、可能是服务器挂了、也可能是服务器上的 sshd 进程挂了,…,可能是技术问题,也可能是非技术问题,可以找出无数可能。

我常遇到或者说每天都遇到的情形是,离开办公桌前忘了退出 ssh 会话。工作的时候长时间 ssh 到服务器上,工作完盖上 Mac 走人,回家后发现那些没退出的 ssh 会话还挂在那里,无法退出、无法 Ctrl+C、无法做任何操作。我的粗暴做法通常是直接关闭 Terminal 后重新开一个新的;如果用的不是图形系统,没有窗口可以关闭,那还要启用另一个终端找到相关进程后 kill 掉,如果每天都要搞这么几次还是挺烦人的。今天无意中从同事那里学到了一个小技巧,在那些没退出的 ssh 会话里用 ~. “优雅” 的断开连接。

~.

查看一下 man 帮助文件发现已经有说明,惭愧的是用了这么多年 ssh 才发现有这么一招:

$ man ssh
...
ESCAPE CHARACTERS
     ...

     The supported escapes (assuming the default `~') are:

     ~.      Disconnect.