2015年7月

我们经常会看到文件名和文件夹名。大多数时候文件/文件夹的名字和内容相关并以数字和字母开头。字母加数字的文件名最常见,应用也很广泛,但总会需要处理一些包含特殊字符的文件名/文件夹名。

注意:我们可能有各种类型的文件,但是为了简单以及方便实现,在本文中我们只用文本文件(.txt)做演示。

最常见的文件名例子:

abc.txt
avi.txt
debian.txt
...

数字文件名例子:

121.txt
3221.txt
674659.txt
...

字母数字文件名例子:

eg84235.txt
3kf43nl2.txt
2323ddw.txt
...

包含特殊字符的文件名的例子,并不常见:

#232.txt
#bkf.txt
#bjsd3469.txt
#121nkfd.txt
-2232.txt
-fbjdew.txt
-gi32kj.txt
--321.txt
--bk34.txt
...

一个显而易见的问题是 - 在这个星球上有谁会创建和处理包含井号(#),分号(;),破折号(-)或其他特殊字符的文件/文件夹啊。

我和你想的一样,这种文件名确实不常见,不过在你必须得处理这种文件名的时候你的 shell 也不应该出错或罢工。而且技术上来说,Linux 下的一切比如文件夹、驱动器或其他所有的都被当作文件处理。

处理名字包含破折号(-)的文件

创建以破折号(-)开头的文件,比如 -abx.txt。

$ touch -abc.txt

测试输出

touch: invalid option -- 'b'
Try 'touch --help' for more information.

出现上面错误的原因是,shell 把破折号(-)之后的内容认作参数了,而很明显没有这样的参数,所以报错。

要解决这个问题,我们得告诉 Bash shell(是的,这里以及本文后面的大多数例子都是基于 BASH 环境)不要将特殊字符(这里是破折号)后的字符解释为参数。

有两种方法解决这个错误:

$ touch -- -abc.txt     [方法 #1]
$ touch ./-abc.txt      [方法 #2]

你可以通过运行命令 ls 或 ls -l 列出详细信息来检查通过上面两种方式创建的文件。

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 11:05 -abc.txt

要编辑上述文件可以这样:

$ nano -- -abc.txt 
或者 
$ nano ./-abc.txt 

注意:你可以将 nano 替换为任何其他你喜欢的编辑器比如说 vim:

$ vim -- -abc.txt 
或者 
$ vim ./-abc.txt 

如果只是简单地移动文件可以这样:

$ mv -- -abc.txt -a.txt
或者
$ mv -- -a.txt -abc.txt

删除这种文件,可以这样:

$ rm -- -abc.txt
或者
$ rm ./-abc.txt 

如果一个目录下有大量这种名字包含破折号的文件,要一次全部删除的话,可以这样:

$ rm ./-*

重要:

  1. 上面讨论的规则可以同样应用于名字中包含任意数量以及任意位置的连接符号的文件。就是说,-a-b-c.txt,ab-c.txt,abc-.txt,等等。
  2. 上面讨论的规则可以同样应用于名字中包含任意数量以及任意位置连接符号的文件夹,除了一种情况,在删除一个文件夹的时候你得这样使用rm -rf

$ rm -rf -- -abc 或者 $ rm -rf ./-abc

处理名字包含井号(#)的文件

符号#在 BASH 里有非常特别的含义。#之后的一切都会被认为是评论,因此会被 BASH 忽略。

通过例子来加深理解:

创建一个名字是 #abc.txt 的文件:

$ touch #abc.txt

测试输出

touch: missing file operand
Try 'touch --help' for more information.

出现上面错误的原因是,BASH 将 #abc.txt 解释为评论而忽略了。所以命令 touch没有收到任何文件作为参数,所以导致这个错误。

要解决这个问题,你可能需要告诉 BASH 不要将 # 解释为评论。

$ touch ./#abc.txt
或者
$ touch '#abc.txt'

检查刚创建的文件:

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 12:14 #abc.txt

现在创建名字中除了开头的其他地方包含 # 的文件。

$ touch ./a#bc.txt
$ touch ./abc#.txt    
或者
$ touch 'a#bc.txt'
$ touch 'abc#.txt'

运行 ‘ls -l‘ 来检查:

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 12:16 a#bc.txt
-rw-r--r-- 1 avi avi 0 Jun  8 12:16 abc#.txt

如果同时创建两个文件(比如 a 和 #bc)会怎么样:

$ touch a.txt #bc.txt

检查刚创建的文件:

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 12:18 a.txt

很明显上面的例子中只创建了文件 a 而文件 #bc 被忽略了。对于上面的情况我们可以这样做,

$ touch a.txt ./#bc.txt
或者
$ touch a.txt '#bc.txt'

检查一下:

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 12:20 a.txt
-rw-r--r-- 1 avi avi 0 Jun  8 12:20 #bc.txt

可以这样移动文件:

$ mv ./#bc.txt ./#cd.txt
或者
$ mv '#bc.txt' '#cd.txt'

这样拷贝:

$ cp ./#cd.txt ./#de.txt
或者
$ cp '#cd.txt' '#de.txt'

可以使用你喜欢的编辑器来编辑文件:

$ vi ./#cd.txt
或者
$ vi '#cd.txt'

$ nano ./#cd.txt
或者
$ nano '#cd.txt'

这样删除:

$ rm ./#bc.txt 
或者
$ rm '#bc.txt'

要删除所有以井号(#)开头的文件,可以这样:

# rm ./#*

处理名字包含分号(;)的文件

如果你还不知道的话,分号在 BASH 里起到命令分隔的作用,其他 shell 可能也是一样的。分号作为分隔符可以让你一次执行几个命令。你碰到过名字包含分号的文件吗?如果没有的话,这里有例子。

创建一个名字包含分号的文件。

$ touch ;abc.txt

测试输出

touch: missing file operand
Try 'touch --help' for more information.
bash: abc.txt: command not found

出现上面错误的原因是,在运行上面命令的时候 BASH 会把 touch 解释为一个命令但是在分号前没有任何文件参数,所以报告错误。然后报告的另一个错误找不到命令 abc.txt,只是因为在分号后 BASH 会期望另一个新的命令,而 abc.txt 并不是一个命令。

要解决这个问题,我们得告诉 BASH 不要将分号解释为命令分隔符,例如:

$ touch ./';abc.txt'
或者
$ touch ';abc.txt'

注意:我们将文件名用单引号 '' 包含起来。这样可以告诉 BASH 分号 ; 是文件名的一部分而不是命令分隔符。

对名字包含分号的文件和文件夹的其他操作(就是,拷贝、移动、删除)可以直接将名字用单引号包含起来就好了。

处理名字包含其他特殊字符的文件/文件夹

文件名包含加号 (+)

不需要任何特殊处理,按平时的方式做就好了,比如下面测试的文件名。

$ touch +12.txt 

文件名包含美元符 ($)

你需要将文件名用单引号括起来,像处理分号那样的方式。然后就很简单了。

$ touch '$12.txt'

文件名包含百分号 (%)

不需要任何特殊处理,当作一个普通文件就可以了。

$ touch %12.txt

文件名包含星号 (*)

需要用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改。)

$ touch *12.txt

注意:当你需要删除星号开头的文件时,千万不要用类似下面的命令。

$ rm *
或者
$ rm -rf *

而是用这样的命令,(LCTT 译注:此处原文有误,已修改)

$ rm ./'*.txt'

文件名包含叹号 (!)

只要将文件名用单引号括起来,其他的就一样了。

$ touch '!12.txt'

文件名包含小老鼠 (@)

没有什么特别的,可以将名字包含小老鼠的文件当作普通文件。

$ touch '@12.txt'

文件名包含 ^

不需要特殊处理。可以将名字包含 ^ 的文件当作普通文件。

$ touch ^12.txt

文件名包含 (&)

将文件名用单引号括起来,然后就可以操作了。

$ touch '&12.txt'

文件名包含括号 ()

如果文件名包含括号,你需要将文件名用单引号括起来。

$ touch '(12.txt)'

文件名包含花括号 {}

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)

$ touch '{12.txt}'

文件名包含尖括号 <>

名字包含尖括号的文件需要用单引号括起来。

$ touch '<12.txt>'

文件名包含方括号 [ ]

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)

$ touch '[12.txt]'

文件名包含下划线 (\_)

这个非常普遍,不需要特殊对待。当作普通文件随意处理。

$ touch _12.txt

文件名包含等号 (=)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)

$ touch '=12.txt'

处理反斜杠 ()

反斜杠会告诉 shell 忽略后面字符的特殊含义。你必须将文件名用单引号括起来,就像处理分号那样。其他的就没什么了。

$ touch '\12.txt'

包含斜杠的特殊情形

除非你的文件系统有问题,否则你不能创建名字包含斜杠的文件。没办法转义斜杠。

所以如果你能创建类似 ‘/12.txt’ 或者 ‘b/c.txt’ 这样的文件,那要么你的文件系统有问题,或者支持 Unicode,这样你可以创建包含斜杠的文件。只是这样并不是真的斜杠,而是一个看起来像斜杠的 Unicode 字符。

文件名包含问号 (?)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)

$ touch '?12.txt'

文件名包含点 (.)

在 Linux 里以点 (.) 开头的文件非常特别,被称为点文件。它们通常是隐藏的配置文件或系统文件。你需要使用 ls 命令的 ‘-a‘ 或 ‘-A‘ 开关来查看这种文件。

创建,编辑,重命名和删除这种文件很直接。

$ touch .12.txt

注意:在 Linux 里你可能碰到名字包含许多点 (.) 的文件。不像其他操作系统,文件名里的点并不意味着分隔名字和扩展后缀。你可以创建名字包含多个点的文件:

$ touch 1.2.3.4.5.6.7.8.9.10.txt

检查一下:

$ ls -l

total 0
-rw-r--r-- 1 avi avi 0 Jun  8 14:32 1.2.3.4.5.6.7.8.9.10.txt

文件名包含逗号 (,)

你可以在文件名中使用逗号,可以有任意多个而不用特殊对待。就像平时普通名字文件那样处理。

$ touch ,12.txt
或者
$ touch ,12,.txt

文件名包含冒号 (:)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)

$ touch ':12.txt'
或者
$ touch ':12:.txt'

文件名包含引号(单引号和双引号)

要在文件名里使用引号,我们需要使用交替规则。例如,如果你需要在文件名里使用单引号,那就用双引号把文件名括起来。而如果你需要在文件名里使用双引号,那就用单引号把文件名括起来。(LCTT 译注:或者如果单引号和双引号混杂的情况,你也可以用反斜杠转义。)

$ touch "15'.txt"

以及

$ touch '15".txt'

文件名包含波浪号 (~)

Linux 下一些像 emacs 这样的文本编辑器在编辑文件的时候会创建备份文件。这个备份文件的名字是在原文件名后面附加一个波浪号。你可以在文件名任意位置使用波浪号,例如:

$ touch ~1a.txt
或者
$touch 2b~.txt

文件名包含空格

创建名字的字符/单词之间包含空格的文件,比如 “hi my name is avishek.txt”。

最好不要在文件名里使用空格,如果你必须要分隔可读的名字,可以使用下划线或横杠。不过,你还是需要创建这样的文件的话,你可以用反斜杠来转义下一个字符。要创建上面名字的文件可以这样做。

$ touch hi\ my\ name\ is\ avishek.txt

hi my name is avishek.txt

我已经尝试覆盖你可能碰到的所有情况。上面大多数测试都在 BASH Shell 里完成,可能在其他 shell 下会有差异。

如果你觉得我遗漏了什么(这很正常也符合人性),请把你的建议发表到下面的评论里。保持联系,多评论。不要走开!求点赞求分享求扩散!


via: http://www.tecmint.com/manage-linux-filenames-with-special-characters/

作者:Avishek Kumar 译者:zpl1025 校对:wxy

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

如果你要在Ubuntu 15.04上安装Node.js的话,这篇教程对你来说肯定很重要。Node.js从本质上来说就是一个运行在服务端上的封装好了输入输出流的javascript程序。Node.js巧妙的使用单线程的事件循环来处理高吞吐量和非阻塞IO。同时它也是一个提供了通过操作系统读写文件和网络操作功能的平台层。所以这篇文章将展示在Ubuntu 15.04 server上不同的安装Node.Js的方式。

安装Node.JS 的方法

有许多安装Node.JS的不同的方法,我们可以选择其一。通过本篇文章我们将手把手带着你在Ubuntu 15.04上安装Node.Js,在此之前请卸载旧版本的包以免发生包冲突。

  • 从源代码安装Node.JS
  • 用包管理器安装Node.JS
  • 从Github远程库安装Node.JS
  • 用NVM安装Node.JS

1) 从源代码安装Node.JS

让我们开始从源代码安装Node.JS之前,请确认系统上的所有的依赖包都已经更新到最新版本。然后跟着以下步骤来开始安装:

步骤1: 升级系统

用以下命令来升级系统,并且安装一些Node.JS必要的包。

root@ubuntu-15:~# apt-get update
root@ubuntu-15:~# apt-get install python gcc make g++

步骤2: 获取Node.JS的源代码

安装好依赖包之后我们可以从官方网站上下载Node.JS的源代码。下载以及解压的命令如下:

root@ubuntu-15:~# wget http://nodejs.org/dist/v0.12.4/node-v0.12.4.tar.gz
root@ubuntu-15:~# tar zxvf node-v0.12.4.tar.gz

步骤3: 开始安装

现在我们进入源代码的目录,然后运行.configure文件

NodeJS Configure

root@ubuntu-15:~# ls
node-v0.12.4 node-v0.12.4.tar.gz
root@ubuntu-15:~# cd node-v0.12.4/
root@ubuntu-15:~/node-v0.12.4# ./configure
root@ubuntu-15:~/node-v0.12.4# make install

安装后测试

只要运行一下上面的命令就顺利安装好了Node.JS,现在我们来确认一下版本信息和测试以下Node.JS是否可以运行输出。

root@ubuntu-15:~/node-v0.12.4# node -v
v0.12.4

Node.Js Test

创建一个以.js为扩展名的文件然后用Node的命令运行

root@ubuntu-15:~/node-v0.12.4# touch helo_test.js
root@ubuntu-15:~/node-v0.12.4# vim helo_test.js
console.log('Hello World');

现在我们用Node的命令运行文件

root@ubuntu-15:~/node-v0.12.4# node helo_test.js
Hello World

输出的结果证明我们已经成功的在Ubuntu 15.04安装好了Node.JS,同时我们也能运行JavaScript文件。

2) 利用包管理器安装Node.JS

在Ubuntu下用包管理器安装Node.JS是非常简单的,只要增加NodeSource的个人软件包档案(PPA)即可。

我们将下面通过PPA安装Node.JS。

步骤1: 用curl获取源代码

在我们用curl获取源代码之前,我们必须先升级操作系统,然后用curl命令获取NodeSource添加到本地仓库。

root@ubuntu-15:~#apt-get update
root@ubuntu-15:~# curl -sL https://deb.nodesource.com/setup | sudo bash -

curl将运行以下任务

## Installing the NodeSource Node.js 0.10 repo...
## Populating apt-get cache...
## Confirming "vivid" is supported...
## Adding the NodeSource signing key to your keyring...
## Creating apt sources list file for the NodeSource Node.js 0.10 repo...
## Running `apt-get update` for you...
Fetched 6,411 B in 5s (1,077 B/s)
Reading package lists... Done
## Run `apt-get install nodejs` (as root) to install Node.js 0.10 and npm

步骤2: 安装NodeJS和NPM

运行以上命令之后如果输出如上所示,我们可以用apt-get命令来安装NodeJS和NPM包。

root@ubuntu-15:~# apt-get install nodejs

NodeJS Install

步骤3: 安装一些必备的工具

通过以下命令来安装编译安装一些我们必需的本地插件。

root@ubuntu-15:~# apt-get install -y build-essential

通过Node.JS Shell来测试

测试Node.JS的步骤与之前使用源代码安装相似,通过以下node命令来确认Node.JS是否完全安装好:

root@ubuntu-15:~# node
> console.log('Node.js Installed Using Package Manager');
Node.js Installed Using Package Manager

root@ubuntu-15:~# node
> a = [1,2,3,4,5]
[ 1, 2, 3, 4, 5 ]
> typeof a
'object'
> 5 + 2
7
>
(^C again to quit)
>
root@ubuntu-15:~#

使用NodeJS应用进行简单的测试

REPL是一个Node.js的shell,任何有效的JavaScript代码都能在REPL下运行通过。所以让我们看看在Node.JS下的REPL是什么样子吧。

root@ubuntu-15:~# node
> var repl = require("repl");
undefined
> repl.start("> ");

Press Enter and it will show out put like this:
> { domain: null,
_events: {},
_maxListeners: 10,
useGlobal: false,
ignoreUndefined: false,
eval: [Function],
inputStream:
{ _connecting: false,
_handle:
{ fd: 0,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 0,
buffer: [],
length: 0,
pipes: null,
...
...

以下是可以在REPL下使用的命令列表

REPL Manual

使用NodeJS的包管理器

NPM是一个提供给node脚本持续生命力的命令行工具,它能通过package.json来安装和管理依赖包。最开始从初始化命令init开始

root@ubuntu-15:~# npm init

NPM starting

3) 从Github远程库安装Node.JS

在这个方法中我们需要一些步骤来把Node.JS从Github的远程的仓库克隆到本地仓库目录

在开始克隆(clone)包到本地并且配制之前,我们要先安装以下依赖包

root@ubuntu-15:~# apt-get install g++ curl make libssl-dev apache2-utils git-core

现在我们开始用git命令克隆到本地并且转到配制目录

root@ubuntu-15:~# git clone git://github.com/ry/node.git
root@ubuntu-15:~# cd node/

Git Clone NodeJS

clone仓库之后,通过运行.config命令来编译生成完整的安装包。

root@ubuntu-15:~# ./configure

Configure Node

运行make install命令之后耐心等待几分钟,程序将会安装好Node.JS。

root@ubuntu-15:~/node# make install
root@ubuntu-15:~/node# node -v
v0.13.0-pre

测试Node.JS

root@ubuntu-15:~/node# node
> a = [1,2,3,4,5,6,7]
[ 1, 2, 3, 4, 5, 6, 7 ]
> typeof a
'object'
> 6 + 5
11
>
(^C again to quit)
>
root@ubuntu-15:~/node#

4) 通过NVM安装Node.JS

在最后一种方法中我们我们将用NVM来比较容易安装Node.JS。安装和配制Node.JS,这是最好的方法之一,它可以供我们选择要安装的版本。

在安装之前,请确认本机以前的安装包已经被卸载。

步骤1: 安装依赖包

首先升级Ubuntu Server系统,然后安装以下安装Node.JS和使用NVM所要依赖的包。用curl命令从git上下载NVM到本地仓库:

root@ubuntu-15:~# apt-get install build-essential libssl-dev
root@ubuntu-15:~# curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh

NVM Curl

步骤2: 修改Home环境

用curl从NVM下载必需的包到用户的home目录之后,我们需要修改bash的配置文件添加NVM,之后只要重新登录中断或者用如下命令更新即可。

root@ubuntu-15:~# source ~/.profile

现在我们可以用NVM来设置默认的NVM的版本,或者用如下命令来指定之前版本:

root@ubuntu-15:~# nvm ls
root@ubuntu-15:~# nvm alias default 0.12.4

NVM Default

步骤3: 使用NVM

我们已经通过NVM成功的安装了Node.JS,所以我们现在可以使用各种有用的命令。

NVM Manual

总结

现在我们已经准备好了在服务端安装Node.JS,你可以从我们说的四种方式中选择最合适你的方式在最新的Ubuntu 15.04上来安装Node.JS,安装好之后你就可以利用Node.JS来编写你的代码。


via: http://linoxide.com/ubuntu-how-to/setup-node-js-ubuntu-15-04-different-methods/

作者:Kashif Siddique 译者:NearTan 校对:wxy

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

服务器管理员需要维护系统并保持更新和安全。每天需要运行大量的指令。有些系统进程会记录日志。这些日志不断更新。为了检查这些更新,需要重复地执行命令。比如,为了读取一个日志文件需要使用head、tail、cat等命令。这些命令需要重复地执行。而watch命令可以用于定期地执行一个命令。

Watch 命令

watch是一个简单的命令,只有几个选项。watch命令的基本语法是:

watch [-dhvt] [-n <seconds>] [--differences[=cumulative]] [--help] [--interval=<seconds>] [--no-title] [--version] <command>

watch命令默认每隔2秒执行后面参数给出的命令。这个时间根据的是命令执行结束到上次执行的间隔来算的。比如,watch命令可以用于监测日志更新,更新是在文件的后面追加新的内容,因此可以用tail命令来检测文件的更新(LCTT 译注:可以直接使用 tail -f 主动跟踪某个文件的更新,而不用使用 watch。)。这个命令会持续地运行直到你按下 CTRL + C回到提示符。

例子

每两秒监测 errors/notices/warning 生成的情况。

watch tail /var/log/messages

tail messages

按指定的时间间隔监测磁盘的使用率。

watch df -h

df -h

对磁盘管理员而言,关注高I/O等待导致的磁盘操作尤其是mysql事务是很重要的。

watch mysqladmin processlist

processlist

监测服务器负载和运行时间。

watch uptime

uptime

监测exim给用户发送通知的队列大小。

watch exim -bpc

exim -bpc

1) 指定延迟

watch [-n <seconds>] <command>

命令默认运行的时间间隔可用-n改变,下面的命令会在5秒后运行后面的命令:

watch -n 5 date

date 5 seconds

2) 连续输出比较

如果你使用-d选项,它会累次地高亮第一次和下一次命令之间输出的差别。

watch [-d or --differences[=cumulative]] <command>

例子 1,用下面的命令连续地输出时间并观察高亮出来的不同部分。

watch -n 15 -d date

第一次执行date的输出会被记录,15秒后会重复运行命令。

Difference A

在下一次执行时,可以看到输出除了被高亮的秒数从14到29之外其他的都一样。

Difference A

例子 2,让我们来体验一下两个连续的“uptime”命令输出的不同。

watch -n 20 -d uptime

uptime

现在列出了时间和3个负载快照之间的不同。

10b

3) 不带标题输出

如果你不希望显示更多关于延迟和实际命令的信息可以使用-t选项。

watch [-t | --no-title] <command>

让我们看下下面例子命令的输出:

watch -t date

watch without title

Watch 帮助

可以在ssh中输入下面的命令来得到watch的简要帮助。

watch -h [--help]

watch help

Watch 版本

在ssh终端中运行下面的命令来检查watch的版本。

watch -v [--version]

version

不足

不幸的是,在终端大小调整时,屏幕不能在下次运行前重画。所有用--difference高亮的内容也会在更新时丢失。

总结

watch对系统管理员而言是一个非常强大的工具,因为它可以用于监控、日志、运维、性能和系统运行时的吞吐量。人们可以非常简单地格式化和推延watch的输出。任何Linux命令/程序或脚本可以按照所需监测和连续输出。


via: http://linoxide.com/linux-command/linux-watch-command/

作者:Aun Raza 译者:geekpi 校对:wxy

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

这次采访是《Linux For You》杂志在2007年进行的,现在我们发表在这里是为了存档的目的。

Q:对于 Linux 内核,未来的计划/道路/提升是怎样的?

Linus:我从来没有太多的预见性 — 与其从宏大的计划上看未来,我倾向于从一个相对短的时间框架,比如“几个月之后的事情”。我是一个忠实的‘细节成败论’的信仰者,如果你抓住了细节,再大的问题也会大事化小,小事化无。

所以,对于五年后内核会是什么样,我真的没有任何远见 — 仅仅是希望我们能够持续专注于Linux的发展。实际上,对于我个人来说,我最担心的事情之一甚至不是技术问题,而是确保这个‘过程’正常,这样人们才可以相互协作好。

Q:你怎么看 Linux 和 Solaris 之间的关系在未来的发展?它会如何使用户受益?

Linus:我并没有看到太多交叉的地方,除了我认为 Solaris 会使用更多的 Linux 用户空间工具(对我自己来说并没有太多关注这个,因为我真的只关心内核)。Linux 桌面比起传统 Solaris 桌面好多了,而且我希望 Solaris 移植越来越多的 Linux 的东西,朝着一个更加类 Linux 的模式前进。(LCTT 译注:时至今日,我们还需要讨论 Solaris 吗?/cry ,但是当时,整个开源社区确实期望接受 Solaris 一些遗产。)

从纯内核方面讲,许可证的存在意味着没有太多的合作空间,但是如果这种情况发生改变将会变得很有趣。Sun 已经声称将在 GPL(v2 或 v3)下授权 Solaris,如果这种许可证的差异消失,那么会导致一些有趣的技术出现。但对此,我持观望态度。

Q:现在 GPL v3 已经完成并发布了,你是否预见有什么情况会鼓励你开始移植内核到 Solaris 上去?或者,从你的角度看,它是否很糟糕以至于你从来没考虑过它?

Linus:我觉得相比于早先的草稿,v3 有了很多提高,并且我也不认为它是一个糟糕的许可证。我只是认为它没有 GPLv2 一样‘伟大’。

所以,如果没有 GPLv2,我觉得自己将会使用 GPLv3。不过,既然我已经有了一个更好的选择,我为什么还要考虑它呢?

这就是说,我始终秉承实用主义精神,并且我认为“ GPLv3 不像 GPLv2 一样好”这件事并不是一个‘非黑即白’的问题。这就像是一个天平,如果 GPLv3 有了其他的优点作为砝码,很有可能那些优点会让我对 GPLv3 更偏爱一些。

恕我直言,我到现在还并没有看到任何优点,但是如果 Solaris 真的在 GPLv3 下发布,可能避免不必要的许可证不兼容性这一条就分量足够了,足以值得我们去尝试将 Linux 的内核重新在 GPLv3 许可证下发布。不过,请不要误解,我认为这是不大可能的。但是我确实想澄清我本质上并不是一个许可证偏执者。我认为 GPLv2 是毫无疑问的好许可证,但是许可证并不是一切。(LCTT 译注:事实上,Solaris/OpenSolaris 最终也没采用 GPL 许可协议发布,而 2010年之后,已经没有什么动静了。而 Linux 内核最终也没有更换到 GPLv3 上。)

总的来说,我使用很多其他许可证下的程序。我可能没有把任何一个我自己做的项目放在 BSD(或 X11—MIT)许可证下,但是我认为它是一个伟大的许可证,对于其他项目来说,它可能是最佳的选择。

Q:目前有没有任何你想特别提出作为 Linux 内核的关键贡献者的印度人?

(LCTT 译注:本篇访谈中提到多次印度,是因为访谈者是印度人。)

Linus:我不得不承认,我并没有与来自印度的任何人直接合作过,尽管我已经非常有意识地努力建立一个规模庞大的内核开发团队,这样我不用总是独自工作。

我相信大多数人的社交基本上是受限制的,只对很少的人十分了解(比如你最亲近的家人和朋友),我也努力构造这样一个开发模型来改变这种状况:通过一个‘开发者网络’,人们可以在此互动,可能是与一批你信任的人,而且那些人反过来与他们信任的一群人互动。

所以,我偶然会与上百个发给我一两个不确定的补丁的开发者联系。我试着去建立一些由我熟知的人组成的小团体,我认为那就是人们工作的方式,当然也是我喜欢工作的方式。

同时,坦白地说,我甚至不知道许多与我一起工作的人生活在哪里。地理位置成了十分次要的东西。所以我很确信与我工作最紧密的前10—15个人中,没有印度的,可能这话稍后传到公众耳里,然后被指出确实有一些人来自那里!

Q:因为 Linux 的内核开发对你依赖如此严重,你如何计划组织或重组,让它在没有你的情况下继续发展,假设你决定花更多的时间在你自己的生活和家庭上面的话?

Linus:现在 Linux 比我重要得多,为了今天这一步我已经工作了很长时间。是的,我仍然十分密切地参与其中,而且我对其有着想当大的日常影响,我最终会是这样一个人——在某种程度上,扮演着许多内核开发活跃者的中心;但是,我不会说 Linux “严重依赖”于我。

所以,如果我得了心脏病并且明天就死了(很高兴没这种可能:我显然在任何方面都很健康),人们肯定会注意到,但是有成千上万的人为内核工作,并且不止一两个人能够毫无困难地接替我的角色。

Q:印度是软件工程师的主要产地之一,但是我们没有在 Linux 领域做太多贡献。你觉得为什么印度人没有积极参与Linux?如果我们鼓励印度人参与并为 Linux 做更大的贡献,你觉得如何?你会乐意用你个人作为榜样激励印度工程师吗?

Linus:对我来说,这确实是一个不好回答的问题。参与开源取决于两方面的基础条件:信息流和文化(用你的话说是互联网和教育),我甚至不知道这其中哪个是最大的障碍。

在很多方面,至少在那些印度讲英语文化的地方,参与 Linux 和其他开源项目是相对容易的,如果仅仅是由于语言门槛的话。这当然比起亚洲的许多地方,甚至欧洲的一些地方要容易些。

当然,这只是一些人,并不等同于印度的大部分群体,而且我自己关于印度的情况也知道不多,甚至没法不太负责的猜测最好的途径是什么。我猜一个热情的本地用户社区会是最好的途径,而且我猜测你们已经拥有这样的社区了。

至于我的‘偶像’形象,我自己不以为然。我不是一个伟大的公众演讲者,而且我最近些年已经避免出游,因为被看做符号化的‘偶像’让我很不自在。我就是一个工程师而已,而且我仅仅是喜欢我做的事情,并与社会上其他人一起工作。

Q:什么样的理由会让你考虑去访问印度?

Linus:如前一个回答中提到,我十分讨厌公开演讲,所以我才想避免开会等等这些事。我更愿意某天去印度度个假,但是如果我这样做,我可能悄悄地干 — 出行之前不告诉任何人,仅仅作为一个游客去游览印度!(LCTT 译注:所以 Linus 不来中国的道理是同样的,除非在中国召开一次世界性的 LinuxCon。)

Q:最近你好像在抨击 Subversion 与 CVS,质问他们的架构基础。现在你已经从 Subversion 和 CVS 社区那里得到回应,你是否改变了看法,还是说并没有被说服?

Linus:因为我发现这个争论很有趣,所以我想做一个强硬的声明。换句话说,我确实‘喜欢’争论。并不是不经思考的,但是我确实想要让争论更热烈些,而不仅仅是完全的柏拉图式的。

做出强硬的争论有时会引来一个非常合理的反驳,然后我会很高兴地说:“噢,好吧,你是对的。”

但是话说回来,对 SVN/CVS 并不会发生这种情况。我怀疑很多人并不是真的很喜欢 CVS,所以我真的不觉得会有谁坚持认为 CVS 就是一切,而不是一个老旧系统。要是我知道之前就有人这样认为的话,我就不会那么不礼貌地反对 SVN(嘿,这么说没错 — 我真的不是一个非常礼貌的家伙!),我不相信任何人会认为 SVN 是‘好的’。

我认为,SVN 就是一个‘还好’的经典案例。人们过去经常使用 SVN,并且它也‘还好’地广泛使用,但是它的‘还好’就如 DOS 与 Windows 的‘还好’一样。不是什么伟大的技术,只是普遍适用而已,同时它对人们来说运行良好,看着十分熟悉。但是很少有人以此为傲,或者对其感到兴奋。

Git,从另外方面讲,其身后有一些‘UNIX 哲学’,这和 UNIX 无关。实质上,就像原始的 UNIX,在它身后有一个基本理念。对 UNIX 来说,最底层的哲学就是,“所有东西只是一个文件”。对 Git 来说,“则是每个东西只是内容寻址数据库中的一个对象”。

Q:现在如此多的发行是好事还是坏事?选择是很有意思的,但是选择太多了就是干扰。相较于这么多的人每天花费数小时去构建成百上千的发行版,如果人们可以一起来支持少数的发行版,这样在企业级市场去挑战微软是不是更容易些呢?对此你怎么看?

Linus:我认为多个发行版是开源不可回避的部分。它会造成困惑吗?当然。它会变得低效率吗?是的。但是我喜欢拿它与政治比较:‘民主’也有那些令人困惑的选择,往往没有任何一个选择是你‘真正’想要的。而且有时候,如果你不需要操心选举、不同党派和联合等等方面的困惑的话,你可能会感觉事情更加容易一些,更有效率一些。

但是最后我想说,选择可能会导致低效率,但是它也让每个人至少保留了‘所谓的’诚信。我们可能都希望我们的政治家更诚信,我们也希望不同的发行版可以让我们有一天有其他的选择,而如果没有选择的话,事情可能会更糟。

Q:为什么你觉得 CFS 比 SD 更好?

Linus:一部分原因是我与 Ingo [Molnar] 工作过很长一段时间,也就是说,我了解他,并且知道他会对发生的任何问题非常负责。那种品质是非常重要的。

但是一部分原因就简单的与用户有关,大多数人实际上表示 CFS 比 SD 好。包括许多 3D 游戏方面(这是人们声称 SD 最强的一点)。

尽管如此,我认为并不是任何一段代码都十分‘完美’。最好的情况是,想成为 SD 支持者的人会努力提高 SD,从而通过其它方式取得了平衡 — 而我们会保持两个阵营都尝试有趣的事情,因为内部的竞争会刺激他们。

Q:在 Google 的一次关于 Git 的访谈中,有人问你如何将当前集中存放的超大代码库迁移到 git 上,而不用将开发工作停止六个月。你对此的回答是什么?

Linus:啊哈,那个问题我在现场没有听清楚(在录音里,问题会听得更清楚些),当我回头去听录制的音频,注意到了我没有回答他的问题,但是我觉得这问题他问过。

无论如何,我们确实有很多导入的工具,所以你实际上可以仅仅是将一个大的项目从任何其他的早期的 SCM (源代码控制系统)导入到 git 里,但问题显然不是经常以导入动作本身结束,而是需要‘习惯’这种新模式!

坦白来说,我认为关于如何‘习惯它’没有任何其他答案,而只能是去开始使用和尝试它。显然,你不会冒险率先导入你现有的最大、最重要的项目,那确实会导致工作停顿下来,然后使得每个人都很不高兴。

所以没有任何理智健全的人会拥护在一夜之间将一切移到 git 上去,并强迫人们改变他们的环境。是的,你需要从公司里的小项目开始,可能是一些由一个小组主要控制和维护的项目,然后开始转移其到 git。这是你能让人们习惯这种模式的方式,你应该以一个核心的组开始,他们知道 git 如何工作,如何在公司里面使用它。

接着,你就会铺展开来。并不需要一次到位。你会导入越来越多的项目 — 甚至是在你公司里采用‘单一大型仓库’模式;那个仓库基本上是作为许多模块的集合,因为让每个人去检查每件事不是一个可执行的工作模型(除非这个‘每件事’并不非常大)。

所以,你基本上只会一次转移一个模块,直到你发现使用 git 是如此酸爽,这时你可以移植余下的所有(或者‘余下’的太旧了,没有人用了)。

git 最赞的一个功能是,它实际上可以同很多其他 SCM 相处很好。很多 git 用户使用它的时候,与他们一起工作的人并没有发现,因为他们看到 git 的结果,会联想到一些传统的 SCM 上去。

Q:Linux 用了你在 Transmeta(全美达)上实现备用指令集的经验吗?[Transmeta Crusoe 芯片看起来像一个非常轻量级的 CPU — 记得有一台 Burroughs B1000 解释器,它实际上实现了多个虚拟机。有的用于系统软件,有的用于 Cobol,还有的用于 Fortran;如果没错的话,那么人们可以在芯片上实现 Burroughs 6/7000 或者 HP3000 类似的堆栈架构,或适用于 JVM 的指令集,等等。(LCTT 译注:Linus 于 1997-2003 期间就职于全美达)]

Linus:我们确实有一些备选的结构集合,不过我不打算谈论太多这个,我可以说的是我们已经做了一个混合结构集合的公开演示。我们有一个技术展示,在那里你同时可以跑 x86 指令和 Java 字节码(实际上,它是一个轻量的扩展 pico—java,iirc)。

我想我们展示的这个应用会在 Linux 上运行 DOOM,这里 Linux 的部分是一个完全标准 x86 发行版。但是 DOOM 的二进制程序是一个特定的编译版本,它实际上编译为 pico-java 代码。而 CPU 最终以相同的方式来运行它们——从 JIT 到原生 VLIW 指令集。

(选择 DOOM 的原因仅仅是其源代码可用,并且游戏的核心部分非常小,足以很容易拿它来做一个验证 — 而且它也显然看起来十分有趣。)

有更多的事情是在内部运作,但是我不能谈论他们。而且实际上,就我个人而言,对 Java 不怎么感冒。

Q:386BSD 衍生了 NetBSD,FreeBSD 和 OpenBSD,在 Linux 出现之前已经发展不错了,但是 Linux 传播比 386BSD 及其衍生者更为广泛。这在多大程度上左右你对许可证的选择,这个选择的发展过程是怎样的?你不认为比起 GPLv2 来,是 GPLv3 创造了发展空间,迄今为止,让 Linux 比 BSD 变得更好?

Linus:我认为这不仅是一个许可证问题,也是一个社区及人格问题。BSD 的许可证总是鼓励分叉,但是这也意味着,如果某些人取得了成功并做了商业性的分叉,他并不需要将他的修改返回来。因此,哪怕实际上这种事情没有(而实际上,这种事情的确发生了,比如 BSDi),人们也难以建立彼此信任。

相比之下,GPLv2 也鼓励分叉,但是它不仅仅鼓励分叉出去,它也鼓励(并‘要求’)能够融合回来。所以,我们现在达到了新的层次的信任:你‘知道’每个人都被许可证所约束,所以每个人都不会占你便宜。

所以,在我看来,GPLv2 作为许可证来说,它允许人们在要求总是回馈贡献的前提下,在另外的方面取得了最大可能的自由。没有人能阻止你对源代码的改进。

那么,BSD 许可证是更‘自由’的吗?是的,毫无疑问。但是我不会在我在意的任何项目里面使用 BSD 许可证,因为我不仅仅想要自由,我也想要信任,可以让我总是能使用其他人为我的项目所写的代码。

所以对于我来说,GPLv2 最终在‘尽可能自由’上取得了完美的平衡,这样,我们做到了让每个人都能信任,他们总是可以取得源代码并使用它。

这就是为什么我认为 GPLv3 最终并没多大意思,它不再是那种‘返回源代码’的信任;它退化成了‘我写了这些代码,所以我能控制你如何使用它’。

换言之,我只是觉得 GPLv3 太狭隘和自私了。我认为 GPLv2 在‘自由’和‘信任’之间取得伟大的平衡。它不如 BSD 许可证自由,但是它让你安心回馈,而且它符合我认为的‘以德报德’:我给你源代码,你也回馈我源代码。

而 GPLv3 试着控制源代码的‘使用’。现在它就是“我给你我的源代码,如果你使用它的话,你就准备好让我对你的设备动手动脚吧”,看见了没?在我看来,不但小气,而且小心眼。

Q:-rt 代码树的功能正在缓慢而稳定地逐渐集成到主线代码中。你对将剩余的 -rt 树合并到主线代码的看法是什么?(我说的不是 CFS)

Linus: 我不能保证来自 -rt 的一切‘都’会被合并进入标准内核(有一些部分肯定不适合常规的内核),不过是的,这些年来我们实际上将它的大部分都集成进去了,剩下的部分最终以后也会合并进去。

我提倡高效工作,但是我同时也很保守。我退回了一些激进的合并请求,只是因为我需要确保它们对我们所有人都有意义,不仅仅是用于极端情况下的实时环境,而且也对并不需要这种环境的‘普通’用户有用。这解释了为什么这个过程相当缓慢却稳定不断地合并代码,因为它需要足够稳定和有意义。

顺便说一句,这不仅仅是针对 -rt ,它也出现在许多开发中。-rt 出现这种情况是因为它是更‘直接’的内核项目,而且也是因为它的一个主要开发者直接参与到了常规内核开发。通常其它功能的迁移(安全、虚拟内核变化、虚拟化,等等)也遵循类似的方式:他们针对特定的环境进行开发,然后这些功能片段缓慢而稳步地合并到标准内核。

Q:我对 Linux 内核所支持的文件系统发展很感兴趣。你觉得 Reiser4、XFS4、ZFS 以及 Oracle 的新项目哪个更有前途?这些天 ZFS 有不少新闻,Reiser4 也发布了很不错的性能基准测试,XFS4 正紧随其后,而 Oracle 发布的那个也有很多像 Sun 的 ZFS 一样的特性。我们将走向何方呢?以你的观点来看,哪个文件系统更有前途?

Linus: 实际上,就在昨天我们发现了一个 git 的性能问题,有一个用户发现他采用 ZFS 要比 UFS 慢一个数量级(不是在 Linux 下,git 已经得到了许多关注,甚至是来自内核开发团队之外)。所以,我认为许多‘新文件系统’的拥护者部分原因是因为他们了解到旧文件系统的不足,然后(有点不切实际地)期望一个‘崭新的、改进的’文件系统能使一切都完美。

最后,这是一个永无止境的领域,看看谁是最终的赢家——也许并不需要(看起来不需要)一个赢家。几乎总是这样,对文件系统的选择最终取决于负载和环境。

相比你提到的这些文件系统,我个人对基于闪存的硬盘很快就可以供甚至是‘普通’用户使用的这个事实更感到兴奋。当然,它们仍然很昂贵(而且相当的小),但是基于闪存的存储和传统硬盘的性能完全不可同日而语,我怀疑它们最终将对文件系统的设计有巨大的影响。而现在,多数文件系统的设计都是在考虑如何处理硬盘延迟。

Q:操作系统变得越来越不重要。你说过好几次用户根本不应该‘看见’操作系统。应用更为重要。基于浏览器的应用,如 Google 的办公软件影响力越来越大。你认为操作系统将走向何方?

Linus:我并不真的认可‘浏览器 OS’,因为我认为人们总是需要在本地做一些事情。也许是因为安全,或者仅仅是因为隐私的原因。而且即便当到处可以接入时,它也并不是‘无处不在’。

所以我认为,整个‘Web OS’这件事有一部分是真实的,但是另外一部分人们也许忘记了操作系统已经存在了几十年,它已经相当稳定,而且它的发展是有目共睹的。人们真的不应该期望操作系统有魔法般的变化,现在已经不是操作系统刚刚起步的六十年代,甚至连硬件也和过去完全不同了!

所以,别指望一场革命。我认为操作系统将在很大程度上继续它们所擅长的,当然,我们也会进步,但是我不认为会从根本上改变。也许会发生巨变的是界面和操作系统顶层的那些东西(当然,操作系统下面的硬件也会继续进步),这显然才是人们所关心的。

至于操作系统?它显然是应该尽可能隐藏起来的东西。你真的不应该在意它,除非你特别想知道在机器里面真正在发生什么。

Q:最近我听说你正在使用一台 PPC G4/5 作为个人计算机,你使用它来做什么?为什么呢?

Linus:我最终放弃了那台 PowerPC,因为没有人能在这台工作站上做到更多,特别是,自从 x86-64 开始变得越来越强大了。所以这些天,我在用一台标准的 PC,里面是一个普通的 Core 2 Duo CPU。

在其它架构下运行是非常有趣的(alpha 作为我的主要架构运行了好几年,所以这并不是第一次),但是这种 CPU 得当成商品买得到才行。我认为,唯一能取代 x86 架构的,也许未来十年并不需要使用 x86 作为主要架构,我认为或许是 ARM,这得益于移动设备市场的发展。

Q:Linux 对你意味着什么?一种业余爱好、哲学、人生意义、工作、最好的操作系统,还是什么?

Linus:它是所有的这一切。它是爱好,而且是具有深刻意义的爱好。最好的爱好是你‘真的’非常在意它。这些日子里,它显然也是我的工作,我非常高兴工作和兴趣能合二为一。

我不了解所谓的‘哲学’,我并不真的是因为深层次的道德或哲学的原因才做的 Linux,但是可以肯定的是,对开源的深层思考是我非常重视的。所以我并不是因为什么明确的理由做 Linux,也不能说是它在激励我,但是我的确在思考开源是如何工作。

Q:微软的‘黑衣人’有没有和你交谈过?

Linus:我从来没有真正和微软交谈过,没有。我偶尔会和一些微软的人出现再同一个会议上(我比以前参加的会议更多了),但是我从来和他们没有任何关系。我认为彼此都很谨慎吧。


via: http://www.linuxveda.com/2015/06/17/what-happens-to-linux-after-linus/

作者:Swapnil Bhartiya 译者:wi-cuckoowxy 校对:mahua, wxy

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

图形桌面总是很养眼的,它增强了可视化体验,有时也能够提升了某些软件的功能,让软件变得更有趣。但是,在命令行下工作也不需要总是很古板,如果您想在命令行下寻找些乐趣,那么有很多命令给您带来趣味。

Linux是个有趣的操作系统。它提供大量的小型开源工具,从平淡无奇的软件到稀奇古怪的应用。正是这些工具的功能和琳琅满目的选择帮助Linux脱颖而出。让我们一起来看看下面这七个小工具吧。

七彩虹:lolcat

lolcat

lolcat是一个用于将文件或标准输入连接到标准输出(类似常见的cat)的程序,但是它会为输出添加七彩的颜色。

lolcat通常和其他诸如toilet或figlet等生成文本的应用结合使用。这个软件不应被误认为是一个或多个猫的图像的宏。

lolcat由Moe编写。

网址: github.com

牛郎的牛:cowsay

cowsay

cowsay是一个可配置的开源软件,它用ASCII码生成奶牛的图片,并可以在对话气泡中显示消息。cowsay是用Perl写的。

cowsay并不仅仅只能显示奶牛。它能生成预先制作的图片或者其他动物,包括鸭子、考拉、麋鹿、小马、绵羊、剑龙和火鸡,以及奶酪、雪人和骷髅。

有一个叫cowthink的应用,与对话的气泡不同,它能在生成奶牛的同时生成思考的气泡。

功能包括:

  • 让脚本变得更有趣
  • Borg模式
  • 可以更改奶牛看起来的样子,比如让奶牛看起来贪婪、偏执、固执、疲倦、古怪、年轻等
  • 图形版变体:xcowsay

网址: nog.net

傻狗:doge

doge

doge是一个简单的每日信息脚本,它基于有些愚蠢但很有趣的doge的梗。它随机的打印一些在语法上有误的句子,有时这些句子基于您电脑中的东西。

doge是一个在2013年非常流行的互联网潮流元素(梗)。这个梗通常由一幅日本柴犬的图片和彩色的文字组成。这些文字故意用一种蹩脚的语气写成了一些互联网的独白。

  • 随机的用不同的颜色和蹩脚的英语写下随机的句子
  • 终端中的柴犬效果非常棒
  • 可以获得系统数据,比如主机名、运行中的程序、当前用户、$EDITOR
  • 如果您安装了lolcat,您可以用它作为点缀: while true; do doge | lolcat -a -d 100 -s 100 -p 1; done
  • 支持标准输入: ls /usr/bin | doge 将显示一些 /usr/bin下的可执行文件。哇噢,还有许多命令行的开关可以过滤词语以及控制词语的频率。

网址: github.com/thiderman/doge

水族箱:ASCIIQuarium

Asciiquarium

ASCIIQuarium是一个以ASCII码方式画出的水族馆/海洋动画。享受生活在您电脑中水底的奇妙生物吧。

想运行ASCIIQuarium,您需要安装Perl的curses包以及Term::Animation模块。请使用sudo apt-get install libcurses-perl来安装前者,使用sudo cpan Term::Animation来安装后者。两个命令都需要在终端中运行。

功能包括:

  • 五彩的鱼儿
  • 有趣的动画,包括钓鱼钩
  • 还有许多的天鹅、鸭子、海豚和船只

网址: www.robobunny.com

蒸汽机车:sl

sl

sl是一个有趣的终端应用,它为那些意外的错将ls输成sl的用户显示一个动画。

我打字通常非常草率,更喜欢速度而不是准确性。但错别字在命令行中是非常危险的。因此sl扮演了一个提醒者,提醒我们注意错误输入的这种坏习惯。它总是会让人咯咯的笑。

功能包括:

  • 使用 -F, 火车在飞翔
  • 使用 -l, 显示一个小型的火车
  • 使用 -a, 看上去发生了意外

网址: github.com/mtoyoda/sl

火焰:aafire

aafire

aafire在终端中显示燃烧的ASCII火焰。它展示了aalib库的强大能力,一个ascii艺术库显示出来。

网址: aa-project.sourceforge.net/aalib

矩阵:CMatrix

CMatrix

CMatrix是一个基于ncurses的程序,它模拟《黑客帝国》(一部电影)中的画面。如果您在一个山洞里度过了上个15年,那么您可能不知道这部1999年的美国科幻电影,主角为 Keanu Reeves, Laurence Fishburne, Carrie-Anne Moss, Hugo Weaving和 Joe Pantoliano。

它可以在终端设置为132x300的情况下工作,并且可以以同样的速率进行滚动或者以用户定义的速度进行异步的滚动。

功能包括:

  • 修改文本颜色
  • 使用粗体字符
  • 异步滚动
  • 使用老式的滚动效果
  • 屏幕保护程序模式

网址: www.asty.org/cmatrix


via: http://www.linuxlinks.com/article/20150614112018846/Humor.html

译者:wwy-hust 校对:Caroline

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

SQLite是一个零配置、无服务端、基于文件的事务型数据库系统。由于它的轻量级,自包含和紧凑的设计,所以当你想要集成数据库到你的程序中时,SQLite是一个非常不错的选择。在这篇文章中,我会展示如何用Perl脚本来创建和访问SQLite数据库。我演示的Perl代码片段是完整的,所以你可以很简单地修改并集成到你的项目中。

访问SQLite的准备

我会使用SQLite DBI Perl驱动来连接到SQLite3。因此你需要在Linux中安装它(和SQLite3一起)。

Debian、 Ubuntu 或者 Linux Mint

$ sudo apt-get install sqlite3 libdbd-sqlite3-perl

CentOS、 Fedora 或者 RHEL

$ sudo yum install sqlite perl-DBD-SQLite

安装后,你可以检查SQLite驱动可以通过下面的脚本访问到。

#!/usr/bin/perl

my @drv = DBI->available_drivers();
print join("\n", @drv), "\n";

如果你运行脚本,你应该会看见下面的输出。

DBM
ExampleP
File
Gofer
Proxy
SQLite
Sponge

Perl SQLite 访问示例

下面就是Perl访问SQLite的示例。这个Perl脚本会演示下面这些SQLite数据库的常规管理。

  • 创建和连接SQLite数据库
  • 在SQLite数据库中创建新表
  • 在表中插入行
  • 在表中搜索和迭代行
  • 在表中更新行
  • 在表中删除行
use DBI;
use strict;

# 定义数据库名称和驱动
my $driver   = "SQLite";
my $db_name = "xmodulo.db";
my $dbd = "DBI:$driver:dbname=$db_name";

# sqlite 没有用户名密码的概念
my $username = "";
my $password = "";

# 创建并连接到数据库
# 以下创建的文件名为 xmodulo.db
my $dbh = DBI->connect($dbd, $username, $password, { RaiseError => 1 })
                      or die $DBI::errstr;
print STDERR "Database opened successfully\n";

# 创建表
my $stmt = qq(CREATE TABLE IF NOT EXISTS NETWORK
             (ID INTEGER PRIMARY KEY     AUTOINCREMENT,
              HOSTNAME       TEXT    NOT NULL,
              IPADDRESS      INT     NOT NULL,
              OS             CHAR(50),
              CPULOAD        REAL););
my $ret = $dbh->do($stmt);
if($ret < 0) {
   print STDERR $DBI::errstr;
} else {
   print STDERR "Table created successfully\n";
}

# 插入三行到表中
$stmt = qq(INSERT INTO NETWORK (HOSTNAME,IPADDRESS,OS,CPULOAD)
           VALUES ('xmodulo', 16843009, 'Ubuntu 14.10', 0.0));
$ret = $dbh->do($stmt) or die $DBI::errstr;

$stmt = qq(INSERT INTO NETWORK (HOSTNAME,IPADDRESS,OS,CPULOAD)
           VALUES ('bert', 16843010, 'CentOS 7', 0.0));
$ret = $dbh->do($stmt) or die $DBI::errstr;

$stmt = qq(INSERT INTO NETWORK (HOSTNAME,IPADDRESS,OS,CPULOAD)
           VALUES ('puppy', 16843011, 'Ubuntu 14.10', 0.0));
$ret = $dbh->do($stmt) or die $DBI::errstr;

# 在表中检索行
$stmt = qq(SELECT id, hostname, os, cpuload from NETWORK;);
my $obj = $dbh->prepare($stmt);
$ret = $obj->execute() or die $DBI::errstr;

if($ret < 0) {
   print STDERR $DBI::errstr;
}
while(my @row = $obj->fetchrow_array()) {
      print "ID: ". $row[0] . "\n";
      print "HOSTNAME: ". $row[1] ."\n";
      print "OS: ". $row[2] ."\n";
      print "CPULOAD: ". $row[3] ."\n\n";
}

# 更新表中的某行
$stmt = qq(UPDATE NETWORK set CPULOAD = 50 where OS='Ubuntu 14.10';);
$ret = $dbh->do($stmt) or die $DBI::errstr;

if( $ret < 0 ) {
   print STDERR $DBI::errstr;
} else {
   print STDERR "A total of $ret rows updated\n";
}

# 从表中删除某行
$stmt = qq(DELETE from NETWORK where ID=2;);
$ret = $dbh->do($stmt) or die $DBI::errstr;

if($ret < 0) {
   print STDERR $DBI::errstr;
} else {
   print STDERR "A total of $ret rows deleted\n";
}

# 断开数据库连接
$dbh->disconnect();
print STDERR "Exit the database\n";

上面的Perl脚本运行成功后会创建一个叫“xmodulo.db”的数据库文件,并会有下面的输出。

Database opened successfully
Table created successfully
ID: 1
HOSTNAME: xmodulo
OS: Ubuntu 14.10
CPULOAD: 0

ID: 2
HOSTNAME: bert
OS: CentOS 7
CPULOAD: 0

ID: 3
HOSTNAME: puppy
OS: Ubuntu 14.10
CPULOAD: 0

A total of 2 rows updated
A total of 1 rows deleted
Exit the database

错误定位

如果你尝试没有安装SQLite DBI驱动的情况下使用Perl访问SQLite的话,你会遇到下面的错误。你必须按开始说的安装DBI驱动。

Can't locate DBI.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./script.pl line 3.
BEGIN failed--compilation aborted at ./script.pl line 3.

via: http://xmodulo.com/access-sqlite-database-perl.html

作者:Dan Nanni 译者:geekpi 校对:wxy

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