ideex.name
2019-09-22T01:25:00+08:00
https://pxx.io/
蒲肖肖
i [at] pxx.io
在 KVM/XEN 虚拟机上安装 Archlinux
https://pxx.io/2016/04/04/kvm-xen-install-archlinux
2016-04-04T00:00:00+08:00
<p>本文适用于在 KVM/XEN 等全虚拟化平台上安装 Archlinux,测试过的平台包括美团云、DigitalOcean、OpenStack、VPS.TO、阿里云。</p>
<p><strong>注意</strong>:DigitalOcean、VPS.TO、阿里云的 IP 地址为手动配置,操作前需要先备份 IP 地址、网关等信息;DigitalOcean 需要选择 Debian 8 作为初始镜像,否则启动时会跳过 GRUB,直接引导内核。</p>
<p>下载镜像:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /
wget http://mirrors.ustc.edu.cn/archlinux/iso/2016.04.01/archlinux-2016.04.01-dual.iso
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/boot/grub/grub.cfg</code>,在第一个 <code class="highlighter-rouge">menuentry</code> 前,添加下面的内容。注意,XEN 平台(如阿里云)中 <code class="highlighter-rouge">/dev/vda1</code> 需要替换为 <code class="highlighter-rouge">/dev/xvda1</code>。</p>
<pre><code class="language-grub">set timeout=30
menuentry "Archlinux Live (x86_64)" {
insmod iso9660
set isofile=/archlinux-2016.04.01-dual.iso
loopback lo0 ${isofile}
linux (lo0)/arch/boot/x86_64/vmlinuz archisolabel=ARCH_201604 img_dev=/dev/vda1 img_loop=${isofile} earlymodules=loop
initrd (lo0)/arch/boot/x86_64/archiso.img
}
</code></pre>
<p>重启,打开网页端 VNC 控制台,应该能看到 GRUB 启动界面,选择 <code class="highlighter-rouge">Archlinux</code>,稍后即可进入 Archlinux 的 Live 环境。</p>
<p>配置网络:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 美团云、OpenStack:</span>
dhcpcd <IFNAME>
<span class="c"># DigitalOcean、VPS.TO、阿里云</span>
ip addr add <IFADDR> dev <IFNAME>
ip route add default via <GATEWAY> dev <IFNAME>
<span class="nb">echo</span> <span class="s1">'nameserver 8.8.8.8'</span> <span class="o">></span>/etc/resolv.conf
</code></pre></div></div>
<p>挂载磁盘:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># XEN 平台把 /dev/vda1 替换为 /dev/xvda1</span>
mount <span class="nt">-o</span> rw,remount /dev/vda1
<span class="c"># 删除原有系统的文件,注意不要删除 archlinux-2016.04.01-dual.iso</span>
<span class="nb">cd</span> /run/archiso/img_dev
<span class="nb">rm</span> <span class="nt">-rf</span> bin boot dev etc ...
</code></pre></div></div>
<p>之后,参照 <a href="https://wiki.archlinux.org/index.php/Install_from_SSH">Install from SSH</a> 安装 Archlinux 到 <code class="highlighter-rouge">/run/archiso/img_dev</code> 下面即可。</p>
Git 学习笔记
https://pxx.io/2015/04/24/git-note
2015-04-24T00:00:00+08:00
<h2 id="git-基础">Git 基础</h2>
<h4 id="1-git-记录文件内容-snapshot而非差异-patch">1. Git 记录文件内容 (snapshot),而非差异 (patch)。</h4>
<p><img src="/images/git-note/01.png" alt="01.png" /></p>
<!--more-->
<p><a id="more"></a></p>
<h4 id="2-文件的三种状态">2. 文件的三种状态</h4>
<p><img src="/images/git-note/02.png" alt="02.png" /></p>
<h4 id="3-基本操作">3. 基本操作</h4>
<ul>
<li>
<p>初始化 Git 仓库</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git init
</code></pre></div> </div>
</li>
<li>
<p>添加文件到暂存区</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add <file>
</code></pre></div> </div>
</li>
<li>
<p>将文件撤出暂存区</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reset HEAD <file>
</code></pre></div> </div>
</li>
<li>
<p>提交</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git commit -m <comment>
</code></pre></div> </div>
</li>
<li>
<p>撤销对工作区的更改(危险)</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git checkout -- <file>
</code></pre></div> </div>
</li>
<li>
<p>添加远程仓库</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git remote add <name> <url>
</code></pre></div> </div>
</li>
<li>
<p>推送到远程仓库</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git push [remote] [branch]
</code></pre></div> </div>
</li>
<li>
<p>从远程仓库抓取</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git retch [remote]
git pull
</code></pre></div> </div>
</li>
</ul>
<h2 id="分支">分支</h2>
<h4 id="1-基本操作">1. 基本操作</h4>
<p>Git 的分支是指向 commit 的指针,因此十分轻量。</p>
<p><img src="/images/git-note/03.png" alt="03.png" /></p>
<p>HEAD 指向当前所在分支。</p>
<p><img src="/images/git-note/04.png" alt="04.png" /></p>
<ul>
<li>
<p>新建分支</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git branch <branch>
git checkout -b <branch>
</code></pre></div> </div>
</li>
<li>
<p>切换分支</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git checkout <branch>
</code></pre></div> </div>
</li>
<li>
<p>删除分支</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git branch -d <branch>
</code></pre></div> </div>
</li>
</ul>
<h4 id="2-merge">2. merge</h4>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git merge <branch>
</code></pre></div></div>
<ol>
<li>
<p>一个分支是另一个的祖先</p>
<p>快进 (Fast forword)<br />
<img src="/images/git-note/05.png" alt="05.png" /></p>
</li>
<li>
<p>分支分叉</p>
<p>把两个分支最新的快照以及二者最新的共同祖先进行三方合并,合并的结果是产生一个新的提交对象<br />
<img src="/images/git-note/06.png" alt="06.png" /></p>
</li>
</ol>
<h4 id="3-rebase">3. rebase</h4>
<p>把一个分支里产生的变化补丁在另一个分支上重新打一遍</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git checkout experiment
git rebase master
</code></pre></div></div>
<p><img src="/images/git-note/07.png" alt="07.png" /><br />
<img src="/images/git-note/08.png" alt="08.png" /></p>
<p>rebase 时应注意,不要对公共分支(一般为 master 分支)进行 rebase,公共分支只允许快进(Fast forward)。</p>
<h2 id="重写历史">重写历史</h2>
<h4 id="1-改变最近一次提交">1. 改变最近一次提交</h4>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git commit --amend
</code></pre></div></div>
<h4 id="2-修改多个提交">2. 修改多个提交</h4>
<p>例如,修改最近 3 个提交:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git rebase -i HEAD~3
</code></pre></div></div>
SOCKS Protocol Version 5
https://pxx.io/2014/12/01/rfc1928
2014-12-01T00:00:00+08:00
<h2 id="介绍">介绍</h2>
<p>网络防火墙可以将组织的内部网络与外部网络(如 Internet)中有效地隔离开。网络防火墙的使用日益广泛。防火墙通常以应用层网关的形式工作在内外网络之间,提供 TELNET、FTP、SMTP 访问。随着越来越多的应用层协议被设计出来以实现全球范围内的信息交流,有必要提供一种通用的框架来使这些协议安全透明地穿过防火墙。而且,在实际应用中,安全的认证方式也是必要的。这个要求起源于不同网络中客户/服务器关系的出现,这个关系需要得到控制并要求有安全的认证。</p>
<p>这个协议设计的目的是为了让使用 TCP/UDP 的应用程序更方便、安全地使用防火墙所提供的服务。从概念上讲,这个协议是介于应用层和传输层之间的中介层(shim-layer),因此不提供 ICMP 转发等由网络层网关提供的服务。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="现有的协议">现有的协议</h2>
<p>现有的协议为 SOCKS4 协议,它为 TELNET、FTP、HTTP、WAIS 和 GOPHER 等基于 TCP 的应用程序提供了不安全的防火墙服务。</p>
<p>新的协议扩展了 SOCKS4 协议,以支持 UDP、安全认证和新的地址协议(域名解析和 IPv6 地址)。</p>
<p>为了实现这个 SOCKS 协议,基于 TCP 的应用程序通常需要重新编译或者重新链接以使用 SOCKS 库中相应的封装函数。</p>
<p><strong>注意:</strong></p>
<p>除非特别注明,所有出现在数据包格式图中的十进制数字均是相应域的长度(以字节为单位)。如果一个域为一个字节,用 X'hh' 的形式来表示这个字节的值。如果某个域为“Variable”,这表示该域的长度是不定的,并且长度定义在一个和这个域相关联(1 – 2 个字节)的域中,或一个数据类型域中。</p>
<h2 id="基于-tcp-协议的客户端">基于 TCP 协议的客户端</h2>
<p>当一个基于 TCP 协议的客户端希望通过防火墙来和一个目标建立连接,它必须与 SOCKS 服务器上的 SOCKS 端口建立一个 TCP 连接。SOCKS 服务通常使用的 TCP 端口号是 1080。连接成功后,客户端进入协议的“协商(negotiation)”阶段:选择认证方式,根据所选的方式进行认证,然后发送请求。SOCKS 服务器检查这个请求,或建立合适的连接,或拒绝这个请求。</p>
<p>客户端连接到服务器后,发送请求来协商协议版本和认证方法:</p>
<table>
<thead>
<tr>
<th style="text-align: center">VER</th>
<th style="text-align: center">NMETHODS</th>
<th style="text-align: center">METHODS</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1 - 255</td>
</tr>
</tbody>
</table>
<p>在这个版本的 SOCKS 协议中,VER 字段被设置为 X'05'。NMETHODS 字段包含了 METHODS 字段中认证方法的个数(以字节为单位)。</p>
<p>服务器从 METHODS 中给定的认证方法中选择一个,然后发送一个 METHOD 选择响应:</p>
<table>
<thead>
<tr>
<th style="text-align: center">VER</th>
<th style="text-align: center">NMETHODS</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
</tr>
</tbody>
</table>
<p>如果选中的 METHOD 是 X'FF',表示客户端提供的所有认证方法都不支持,客户端<strong>必须</strong>断开连接。</p>
<p>当前定义 METHOD 如下:</p>
<ul>
<li>X'00' 不需要认证</li>
<li>X'01' GSSAPI</li>
<li>X'02' 用户名/密码</li>
<li>X'03' - X'7F' 由IANA分配</li>
<li>X'80' to X'FE' 为私人方法所保留的</li>
<li>X'FF' 没有可以接受的方法</li>
</ul>
<p>然后客户和服务器进入由选定认证方法所决定的子协商过程(sub-negotiation)。不同认证方法的子协商过程请参考各自的备忘录。</p>
<p>开发者如果要为自己的新认证方法得到一个方法号,可以联系 IANA。可以参考关于已经被分配号码的文档以得到当前所有方法的列表和相应的协议。</p>
<p>符合本文档的 SOCKS5 实现必须支持 GSSAPI,并且在将来支持用户名/密码认证方式。</p>
<h2 id="请求">请求</h2>
<p>协商过程结束后,客户端发送详细的请求信息。如果协商过程选定的认证方法中有以完整性、认证、安全为目的的封装,请求必须按照该方法所定义的方式进行封装。</p>
<p>SOCKS 请求的格式如下:</p>
<table>
<thead>
<tr>
<th style="text-align: center">VER</th>
<th style="text-align: center">CMD</th>
<th style="text-align: center">RSV</th>
<th style="text-align: center">ATYP</th>
<th style="text-align: center">DST.ADDR</th>
<th style="text-align: center">DST.PORT</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">X'00'</td>
<td style="text-align: center">1</td>
<td style="text-align: center">Variable</td>
<td style="text-align: center">2</td>
</tr>
</tbody>
</table>
<p>其中:</p>
<ul>
<li>VER 协议版本:X'05'</li>
<li>CMD</li>
<li>
<ul>
<li>CONNECT X'01'</li>
</ul>
</li>
<li>
<ul>
<li>BIND X'02'</li>
</ul>
</li>
<li>
<ul>
<li>UPD ASSOCIATE X'03'</li>
</ul>
</li>
<li>RSV 保留</li>
<li>ATYP 地址类型</li>
<li>
<ul>
<li>IPv4 地址 X'01'</li>
</ul>
</li>
<li>
<ul>
<li>域名 X'03'</li>
</ul>
</li>
<li>
<ul>
<li>IPv6 地址 X'04'</li>
</ul>
</li>
<li>DST.ADDR 目的地址</li>
<li>DST.PORT 目的端口号(网络字节序)</li>
</ul>
<p>SOCKS 服务器根据源地址和目的地址来分析请求,然后根据请求类型返回一个或多个应答。</p>
<h2 id="地址">地址</h2>
<p>ATYP 字段描述了地址字段(DST.ADDR,BND.ADDR)所包含的地址类型:</p>
<ul>
<li>X'01'
IPv4 地址,4 个字节</li>
<li>X'03'
域名,地址字段中的第 1 个字节是该域名的长度(以字节为单位),结尾没有 NUL 字符</li>
<li>X'04'
IPv6 地址,16 个字节</li>
</ul>
<h2 id="应答">应答</h2>
<p>SOCKS 服务器分析客户端的请求,然后以下面的格式返回一个应答:</p>
<table>
<thead>
<tr>
<th style="text-align: center">VER</th>
<th style="text-align: center">REP</th>
<th style="text-align: center">RSV</th>
<th style="text-align: center">ATYP</th>
<th style="text-align: center">BND.ADDR</th>
<th style="text-align: center">BND.PORT</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">X'00'</td>
<td style="text-align: center">1</td>
<td style="text-align: center">Variable</td>
<td style="text-align: center">2</td>
</tr>
</tbody>
</table>
<p>其中:</p>
<ul>
<li>VER 协议版本:X'05'</li>
<li>REP 应答字段:</li>
<li>
<ul>
<li>X'00' 成功</li>
</ul>
</li>
<li>
<ul>
<li>X'01' 常规 SOCKS 服务器错误</li>
</ul>
</li>
<li>
<ul>
<li>X'02' 不允许的连接</li>
</ul>
</li>
<li>
<ul>
<li>X'03' 网络不可达</li>
</ul>
</li>
<li>
<ul>
<li>X'04' 主机不可达</li>
</ul>
</li>
<li>
<ul>
<li>X'05' 连接被拒</li>
</ul>
</li>
<li>
<ul>
<li>X'06' TTL 超时</li>
</ul>
</li>
<li>
<ul>
<li>X'07' 不支持的命令</li>
</ul>
</li>
<li>
<ul>
<li>X'08' 不支持的地址类型</li>
</ul>
</li>
<li>
<ul>
<li>X'09' - X'FF' 未定义</li>
</ul>
</li>
<li>RSV 保留</li>
<li>ATYP 地址类型</li>
<li>
<ul>
<li>IPv4 地址 X'01'</li>
</ul>
</li>
<li>
<ul>
<li>域名 X'03'</li>
</ul>
</li>
<li>
<ul>
<li>IPv6 地址 X'04'</li>
</ul>
</li>
<li>BND.ADDR 服务器绑定的地址</li>
<li>BND.PORT 服务器绑定的端口号(网络字节序)</li>
</ul>
<p>标识为 RSV 的字段必须设为 X'00'。</p>
<p>如果选定的认证方法中有以完整性、认证、安全为目的的封装,应答必须按照该方法所定义的方式进行封装。</p>
<h3 id="connect">CONNECT</h3>
<p>在对一个 CONNECT 命令的应答中,BND.PORT 包含了服务器分配的用来连到目标机的端口号,BND.ADDR 则是相应的 IP 地址。由于 SOCKS 服务器通常有多个 IP,应答中的 BND.ADDR 常和客户端连到 SOCKS 服务器的那个 IP 不同。SOCKS 服务器可以利用 DST.ADDR 和 DST.PORT,以及客户端源地址和端口来对一个 CONNECT 请求进行分析。</p>
<h3 id="bind">BIND</h3>
<p>BIND 请求通常被用在那些要求客户端接受来自服务器的连接的协议上。FTP 是一个典型的例子。它建立一个从客户端到服务器的连接来传送命令和状态,而使用另一个从服务器到客户端的连接来传输请求(如LS、GET、PUT)的数据。</p>
<p>通常一个应用层协议的客户端在使用 CONNECT 命令建立主连接后才会使用 BIND 命令建立第二个连接。SOCKS 服务器可以使用 DST.ADDR 和 DST.PORT 来对一个 BIND 进行分析。</p>
<p>在一个 BIND 请求过程中,SOCKS 服务器要发送两个应答给客户端。当服务器建立并绑定一个新的套接口时发送第一个应答。BND.PORT 字段包含 SOCKS 服务器用来监听进入的连接的端口号,BAND.ADDR 字段包含了对应的 IP 地址。客户端通常使用这些信息来告诉(通过主连接或控制连接)服务器连接的汇接点。第二个应答仅发生在所期望到来的连接成功或失败之后。在第二个应答中,BND.PORT 和 BND.ADDR 字段包含了连上来的主机的 IP 地址和端口号。</p>
<h3 id="udp-associate">UDP ASSOCIATE</h3>
<p>UDP ASSOCIATE 请求通常是要求建立一个 UDP 中继来处理到来的 UDP 数据包。DST.ADDR 和 DST.PORT 字段包含客户端所希望用来发送 UDP 数据包的 IP 地址和端口号。服务器可以使用这个信息来限制进入的连接。如果客户端在发送这个请求时没有地址和端口信息,客户端必须用全 0 来填充。</p>
<p>当与 UDP 相对应的 TCP 连接中断时,该 UDP 连接也必须中断。</p>
<p>应答 UDP ASSOCIATE 请求时,BND.PORT 和 BND.ADDR 字段指明了客户端发送 UDP 数据包时的目的端口和目的地址。</p>
<h3 id="应答处理">应答处理</h3>
<p>当一个应答(REP 值不等于 X'00')表明有错误发生时,SOCKS 服务器必须在发送完应答消息后一小段时间内终止 TCP 连接。这段时间应该在发现错误后少于 10 秒。</p>
<p>如果一个应答(REP 值等于 X'00')表明成功,并且请求是 BIND 或 CONNECT 时,客户端就可以开始发送数据了。如果协商的认证方法中有以完整性、认证、安全为目的的封装,这些数据必须按照该方法所定义的方式进行封装。类似的,当以客户机为目的地的数据到达 SOCKS 服务器时,SOCKS 服务器必须用正在使用的方法对这些数据进行封装。</p>
<h3 id="基于udp协议的客户">基于UDP协议的客户</h3>
<p>UDP ASSOCIATE 应答中 BND.PORT 指明了服务器所使用的 UDP 端口,一个基于 UDP 协议的客户必须发送数据报到服务器的该端口上。如果协商的认证方法中有以完整性、认证、安全为目的的封装,这些数据报必须按照该方法所定义的方式进行封装。每个UDP数据报都有一个 UDP 请求头在其首部:</p>
<table>
<thead>
<tr>
<th style="text-align: center">RSV</th>
<th style="text-align: center">FRAG</th>
<th style="text-align: center">ATYP</th>
<th style="text-align: center">DST.ADDR</th>
<th style="text-align: center">DST.PORT</th>
<th style="text-align: center">DATA</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">2</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">Variable</td>
<td style="text-align: center">2</td>
<td style="text-align: center">Variable</td>
</tr>
</tbody>
</table>
<p>其中:</p>
<ul>
<li>RSV 保留</li>
<li>FRAG 当前的分段号</li>
<li>ATYP 地址类型</li>
<li>
<ul>
<li>IPv4 地址 X'01'</li>
</ul>
</li>
<li>
<ul>
<li>域名 X'03'</li>
</ul>
</li>
<li>
<ul>
<li>IPv6 地址 X'04'</li>
</ul>
</li>
<li>DST.ADDR 目的地址</li>
<li>DST.PORT 目的端口号(网络字节序)</li>
<li>DATA 用户数据</li>
</ul>
<p>当 UDP 中继服务器转发一个 UDP 数据报时,不会向客户端发送任何通知。同样,不能转发的数据报将被直接丢弃。当 UDP 中继服务器从远程主机收到一个响应数据报时,也<strong>必须</strong>加上上述 UDP 请求头,并对数据报进行封装。</p>
<p>客户端向 UDP ASSOCIATE 应答中给定的端口号发送数据报时,所用的 IP 地址必须由 SOCKS 服务器告知 UDP 中继服务器。来自其他 IP 地址的数据报将会被丢弃。</p>
<p>FRAG 字段指明数据报是否是一组分片中的一片。如果 SOCKS 服务器要实现这个功能,X'00' 表示数据报是独立的,其他的值则越大越是数据报组的尾端。介于 1 到 127 之间的值说明了该分片在分片序列里的位置。每个接收者都为这些分片提供一个重组队列和一个重组的计时器。这个重组队列必须在重组计时器超时后重新初始化,并丢弃相应的数据报。或者当一个新到达的数据报有一个比当前在处理的数据报序列中最大的 FRAG 值要小时,也必须重新初始化从组队列。重组计时器必须小于5秒。只要有可能,应用程序最好不要使用分片。</p>
<p>分片的实现是可选的,如果某实现不支持分片,所有 FRAG 字段不为 0 的数据报都必须被丢弃。</p>
<p>支持 SOCKS 的 UDP 编程接口必须报告当前可用 UDP 数据报缓存空间小于操作系统提供的实际空间:</p>
<ul>
<li>ATYP 为 X'01'
比实际空间小 10 + 认证方法相关的字节数</li>
<li>ATYP 为 X'03'
比实际空间小 262 + 认证方法相关字节数</li>
<li>ATYP 为 X'04'
比实际空间小 20 + 认证方法相关字节数</li>
</ul>
<h2 id="安全性考虑">安全性考虑</h2>
<p>这篇文档描述了一个用来透过 IP 网络防火墙的应用层协议。这种传输的安全性在很大程度上依赖于特定实现所拥有以及在 SOCKS 客户端与 SOCKS 服务器之间经协商所选定的特殊的认证和封装方式。</p>
<p>系统管理员需要对用户认证方式的选择进行仔细考虑。</p>
<h2 id="参考书目">参考书目</h2>
<p>[1] Koblas, D., “SOCKS”, Proceedings: 1992 Usenix Security Symposium.</p>
计算斐波那契数列
https://pxx.io/2014/08/27/fibonacci
2014-08-27T00:00:00+08:00
<p><a href="https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97">斐波那契数列</a>的定义为:</p>
<ul>
<li>F<sub>0</sub> = 0</li>
<li>F<sub>1</sub> = 1</li>
<li>F<sub>n</sub> = F<sub>n-1</sub> + F<sub>n-2</sub> (n≥2)</li>
</ul>
<p>即:斐波那契数列由0和1开始,之后的每一项均为之前的两数之和。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="计算方法">计算方法</h2>
<h3 id="递归法">递归法</h3>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">long</span> <span class="nf">fibonacci</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="迭代法">迭代法</h3>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">long</span> <span class="nf">fibonacci</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">fib1</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">fib2</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="n">n</span> <span class="o">></span> <span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">fib2</span><span class="p">;</span>
<span class="n">fib2</span> <span class="o">=</span> <span class="n">fib1</span> <span class="o">+</span> <span class="n">fib2</span><span class="p">;</span>
<span class="n">fib1</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
<span class="n">n</span><span class="o">--</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">fib2</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="矩阵">矩阵</h3>
<script type="math/tex; mode=display">% <![CDATA[
\begin{pmatrix}
F_{n+1} \\
F_{n}
\end{pmatrix}
=
\begin{pmatrix}
1 & 1 \\
1 & 0
\end{pmatrix}
\cdot
\begin{pmatrix}
F_{n} \\
F_{n-1}
\end{pmatrix}
\\
\Rightarrow
\begin{pmatrix}
F_{n+1} & F_{n} \\
F_{n} & F_{n-1}
\end{pmatrix}
=
\begin{pmatrix}
1 & 1 \\
1 & 0
\end{pmatrix}
^n %]]></script>
<p>矩阵的乘方可以用快速幂运算来做,时间复杂度为 O(log n)。</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">long</span> <span class="nf">fibonacci</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">register</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">pow</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">}</span> <span class="p">};</span>
<span class="k">register</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">fib</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">}</span> <span class="p">};</span>
<span class="k">while</span> <span class="p">(</span><span class="n">n</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">register</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">&</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">fib</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">fib</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">fib</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">fib</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">fib</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">fib</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">fib</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">fib</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">pow</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
<span class="n">pow</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">tmp</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="n">n</span> <span class="o">>>=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">fib</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>
如何判断域名是否被污染
https://pxx.io/2014/08/24/is-a-domain-polluted
2014-08-24T00:00:00+08:00
<p>Update 2017-11-15: 修复脚本</p>
<p><a href="https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BC%93%E5%AD%98%E6%B1%A1%E6%9F%93">DNS 污染</a>是指一些伪造的 DNS 请求,把域名指往不正确的 IP 地址。DNS 污染是<a href="https://zh.wikipedia.org/wiki/%E9%98%B2%E7%81%AB%E9%95%B7%E5%9F%8E">国内某知名互联网服务</a>的主要手段之一(其他手段包括 IP 封锁,端口封锁,TCP 连接重置等)。那么,如何判断一个域名是否被污染了呢?</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="dns-污染的原理">DNS 污染的原理</h2>
<p>DNS 设计是有缺陷的:</p>
<ol>
<li>数据都是明文的,可以轻松嗅探</li>
<li>缺乏验证机制,无法识别虚假的 DNS 回应</li>
</ol>
<p>只要做关键字匹配,发送虚假 DNS 查询结果即可。</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig twitter.com
<span class="p">;</span> <<<span class="o">>></span> DiG 9.9.2-P2 <<<span class="o">>></span> twitter.com
<span class="p">;;</span> global options: +cmd
<span class="p">;;</span> Got answer:
<span class="p">;;</span> ->>HEADER<span class="o"><<-</span> <span class="no">opcode</span><span class="sh">: QUERY, status: NOERROR, id: 3709
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;twitter.com. IN A
;; ANSWER SECTION:
twitter.com. 300 IN A 37.61.54.158
;; Query time: 38 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Aug 27 00:13:43 2014
;; MSG SIZE rcvd: 56
</span></code></pre></div></div>
<h2 id="判断域名是否被污染">判断域名是否被污染</h2>
<p>墙在做 DNS 污染时是很粗暴的,只要关键字匹配,一律发送虚假的 A 记录。例如,<code class="highlighter-rouge">thisisnottwitter.com</code> 这个域名并不存在,但依然被污染了:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @a.root-servers.net. thisisnottwitter.com
<span class="p">;</span> <<<span class="o">>></span> DiG 9.9.2-P2 <<<span class="o">>></span> @a.root-servers.net. thisisnottwitter.com
<span class="p">;</span> <span class="o">(</span>2 servers found<span class="o">)</span>
<span class="p">;;</span> global options: +cmd
<span class="p">;;</span> Got answer:
<span class="p">;;</span> ->>HEADER<span class="o"><<-</span> <span class="no">opcode</span><span class="sh">: QUERY, status: NOERROR, id: 28008
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;thisisnottwitter.com. IN A
;; ANSWER SECTION:
thisisnottwitter.com. 300 IN A 37.61.54.158
;; Query time: 128 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Wed Aug 27 00:14:47 2014
;; MSG SIZE rcvd: 74
</span></code></pre></div></div>
<p>事实上,根据 DNS 协议,根 DNS 服务器应该返回的是 <code class="highlighter-rouge">com.</code> 的权威域,不可能返回 A 记录。正确的回应应该是这样的:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @a.root-servers.net. thisisnottwitter.com
<span class="p">;</span> <<<span class="o">>></span> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.el6_5.1 <<<span class="o">>></span> @a.root-servers.net. thisisnottwitter.com
<span class="p">;</span> <span class="o">(</span>2 servers found<span class="o">)</span>
<span class="p">;;</span> global options: +cmd
<span class="p">;;</span> Got answer:
<span class="p">;;</span> ->>HEADER<span class="o"><<-</span> <span class="no">opcode</span><span class="sh">: QUERY, status: NOERROR, id: 23058
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 14
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;thisisnottwitter.com. IN A
;; AUTHORITY SECTION:
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
;; ADDITIONAL SECTION:
a.gtld-servers.net. 172800 IN A 192.5.6.30
b.gtld-servers.net. 172800 IN A 192.33.14.30
c.gtld-servers.net. 172800 IN A 192.26.92.30
d.gtld-servers.net. 172800 IN A 192.31.80.30
e.gtld-servers.net. 172800 IN A 192.12.94.30
f.gtld-servers.net. 172800 IN A 192.35.51.30
g.gtld-servers.net. 172800 IN A 192.42.93.30
h.gtld-servers.net. 172800 IN A 192.54.112.30
i.gtld-servers.net. 172800 IN A 192.43.172.30
j.gtld-servers.net. 172800 IN A 192.48.79.30
k.gtld-servers.net. 172800 IN A 192.52.178.30
l.gtld-servers.net. 172800 IN A 192.41.162.30
m.gtld-servers.net. 172800 IN A 192.55.83.30
a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
;; Query time: 122 msec
;; SERVER: 2001:503:ba3e::2:30#53(2001:503:ba3e::2:30)
;; WHEN: Wed Aug 27 00:15:38 2014
;; MSG SIZE rcvd: 498
</span></code></pre></div></div>
<p>根据这一点即可判断某个域名是否被污染。写成 Bash 脚本如下:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="nb">set</span> <span class="nt">-e</span>
usage<span class="o">()</span> <span class="o">{</span>
<span class="nb">echo</span> <span class="s2">"Usage: </span><span class="si">$(</span><span class="nb">basename</span> <span class="nv">$0</span><span class="si">)</span><span class="s2"> domain"</span>
<span class="nb">echo</span> <span class="s2">" -h, --help Show this help"</span>
<span class="o">}</span>
isblocked<span class="o">()</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">[[</span> <span class="si">$(</span>dig @a.root-servers.net. <span class="k">${</span><span class="nv">1</span><span class="k">}</span> | <span class="nb">grep</span> <span class="s1">'ANSWER SECTION'</span><span class="si">)</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
return </span>0
<span class="k">else
return </span>1
<span class="k">fi</span>
<span class="o">}</span>
<span class="nb">set</span> <span class="nt">-e</span>
<span class="o">[[</span> <span class="s2">"$#"</span> <span class="nt">-eq</span> 0 <span class="o">]]</span> <span class="o">&&</span> usage <span class="o">&&</span> <span class="nb">exit </span>0
<span class="nv">domain</span><span class="o">=</span><span class="nv">$1</span>
<span class="k">if </span>isblocked <span class="s2">"</span><span class="k">${</span><span class="nv">domain</span><span class="k">}</span><span class="s2">"</span><span class="p">;</span> <span class="k">then
</span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">domain</span><span class="k">}</span><span class="s2"> is polluted."</span>
<span class="k">else
</span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">domain</span><span class="k">}</span><span class="s2"> is not polluted."</span>
<span class="k">fi</span>
</code></pre></div></div>
幻方
https://pxx.io/2014/08/23/magic-square
2014-08-23T00:00:00+08:00
<p><a href="https://zh.wikipedia.org/wiki/%E5%B9%BB%E6%96%B9">幻方</a>,或称纵横图,由一组排放在正方形中的整数组成,其每行、每列以及两条对角线上的数之和均相等。通常幻方由从 1 到 N<sup>2</sup> 的连续整数组成,其中N为正方形的行或列的数目。因此 N 阶幻方有 N 行 N 列,并且所填充的数为从 1 到 N<sup>2</sup>。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="构造法">构造法</h2>
<p>详见维基百科</p>
<h2 id="代码">代码</h2>
<p>这里贴一个大一时写的代码,用混乱 C 语言写的:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
</span><span class="kt">int</span> <span class="n">_</span><span class="p">[</span><span class="mi">100</span><span class="p">][</span><span class="mi">100</span><span class="p">],</span><span class="n">__</span><span class="p">[</span><span class="mi">50</span><span class="p">][</span><span class="mi">50</span><span class="p">],</span><span class="n">___</span><span class="p">,</span><span class="n">____</span><span class="p">,</span><span class="n">_____</span><span class="p">,</span><span class="n">______</span><span class="p">,</span><span class="n">_______</span><span class="p">,</span><span class="n">________</span><span class="p">;</span><span class="kt">char</span> <span class="o">*</span><span class="n">_________</span><span class="p">;</span><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">__________</span><span class="p">){</span><span class="k">return</span><span class="p">(</span><span class="n">__________</span><span class="o">==</span><span class="mi">1</span><span class="o">&&</span><span class="p">(</span><span class="n">___</span><span class="o">==</span><span class="mi">0</span><span class="o">&&</span><span class="p">(</span><span class="n">printf</span><span class="p">(</span><span class="s">"Enter n(n>0): "</span><span class="p">),</span><span class="n">scanf</span><span class="p">(</span><span class="s">"%d"</span><span class="p">,</span><span class="o">&</span><span class="n">___</span><span class="p">)),((</span><span class="n">___</span><span class="o">&</span><span class="mi">1</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">___</span><span class="o">&</span><span class="mi">1</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_____</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">______</span><span class="o">=</span><span class="p">(</span><span class="n">___</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span><span class="n">_</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">______</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">_______</span><span class="o">=</span><span class="mi">2</span><span class="p">)),(</span><span class="o">!</span><span class="p">(</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o">=</span><span class="mi">1</span><span class="p">)),(((</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">____</span><span class="o">=</span><span class="n">___</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span><span class="n">_____</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span><span class="n">______</span><span class="o">=</span><span class="p">(</span><span class="n">____</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">_______</span><span class="o">=</span><span class="mi">1</span><span class="p">)),</span><span class="n">main</span><span class="p">(</span><span class="mi">0</span><span class="p">))),(</span><span class="n">__________</span><span class="o">==</span><span class="mi">0</span><span class="o">&&</span><span class="p">((((</span><span class="n">___</span><span class="o">&</span><span class="mi">1</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o"><=</span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">))</span><span class="o">||</span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o"><=</span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">))</span><span class="o">||</span><span class="p">(((</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o"><=</span><span class="n">____</span><span class="o">*</span><span class="n">____</span><span class="p">))</span><span class="o">||</span><span class="p">(</span><span class="o">!</span><span class="p">((</span><span class="n">___</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span><span class="o">&&</span><span class="n">printf</span><span class="p">(</span><span class="s">"No solution.</span><span class="se">\n</span><span class="s">"</span><span class="p">))</span><span class="o">&&</span><span class="n">________</span><span class="o"><=</span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">))</span><span class="o">&&</span><span class="p">(((</span><span class="n">_______</span><span class="o"><=</span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">)</span><span class="o">&&</span><span class="p">((((</span><span class="n">___</span><span class="o">&</span><span class="mi">1</span><span class="p">)</span><span class="o">&&</span><span class="p">((((</span><span class="n">_____</span><span class="o">==</span><span class="mi">1</span><span class="o">&&</span><span class="n">______</span><span class="o">==</span><span class="n">___</span><span class="p">)</span><span class="o">||</span><span class="n">_</span><span class="p">[(</span><span class="n">___</span><span class="o">+</span><span class="n">_____</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">%</span><span class="n">___</span><span class="p">][</span><span class="n">______</span><span class="o">%</span><span class="n">___</span><span class="p">])</span><span class="o">?</span><span class="p">(</span><span class="n">_____</span><span class="o">=</span><span class="n">_____</span><span class="o">%</span><span class="n">___</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">_____</span><span class="o">=</span><span class="p">(</span><span class="n">___</span><span class="o">+</span><span class="n">_____</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">%</span><span class="n">___</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">______</span><span class="o">=</span><span class="n">______</span><span class="o">%</span><span class="n">___</span><span class="o">+</span><span class="mi">1</span><span class="p">)),</span><span class="n">_</span><span class="p">[</span><span class="n">_____</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">______</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="p">))),((</span><span class="o">!</span><span class="p">(</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_</span><span class="p">[(</span><span class="n">_______</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="n">___</span><span class="p">][(</span><span class="n">_______</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">___</span><span class="p">]</span><span class="o">=</span><span class="p">((</span><span class="n">_______</span><span class="o">%</span><span class="mi">4</span><span class="o"><</span><span class="mi">2</span><span class="p">)</span><span class="o">^</span><span class="p">((</span><span class="n">_______</span><span class="o">+</span><span class="n">___</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="n">___</span><span class="o">%</span><span class="mi">4</span><span class="o"><</span><span class="mi">2</span><span class="p">))</span><span class="o">?</span><span class="p">(</span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="o">+</span><span class="mi">1</span><span class="o">-</span><span class="n">_______</span><span class="p">)</span><span class="o">:</span><span class="n">_______</span><span class="p">))),(((</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span><span class="o">&&</span><span class="p">((((</span><span class="n">_____</span><span class="o">==</span><span class="mi">1</span><span class="o">&&</span><span class="n">______</span><span class="o">==</span><span class="n">____</span><span class="p">)</span><span class="o">||</span><span class="n">__</span><span class="p">[(</span><span class="n">____</span><span class="o">+</span><span class="n">_____</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">%</span><span class="n">____</span><span class="p">][</span><span class="n">______</span><span class="o">%</span><span class="n">____</span><span class="p">])</span><span class="o">?</span><span class="p">(</span><span class="n">_____</span><span class="o">=</span><span class="n">_____</span><span class="o">%</span><span class="n">____</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">_____</span><span class="o">=</span><span class="p">(</span><span class="n">____</span><span class="o">+</span><span class="n">_____</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">%</span><span class="n">____</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">______</span><span class="o">=</span><span class="n">______</span><span class="o">%</span><span class="n">____</span><span class="o">+</span><span class="mi">1</span><span class="p">)),</span><span class="n">__</span><span class="p">[</span><span class="n">_____</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">______</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="p">,</span><span class="n">_________</span><span class="o">=</span><span class="p">((</span><span class="n">_____</span><span class="o">>=</span><span class="n">___</span><span class="o">/</span><span class="mi">4</span><span class="o">+</span><span class="mi">3</span><span class="p">)</span><span class="o">?</span><span class="s">"</span><span class="se">\3\0\1\2</span><span class="s">"</span><span class="o">:</span><span class="p">(((</span><span class="n">______</span><span class="o">==</span><span class="n">___</span><span class="o">/</span><span class="mi">4</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">?</span><span class="p">(</span><span class="n">_____</span><span class="o">==</span><span class="n">___</span><span class="o">/</span><span class="mi">4</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">_____</span><span class="o">==</span><span class="n">___</span><span class="o">/</span><span class="mi">4</span><span class="o">+</span><span class="mi">2</span><span class="p">))</span><span class="o">?</span><span class="s">"</span><span class="se">\3\0\2\1</span><span class="s">"</span><span class="o">:</span><span class="s">"</span><span class="se">\0\3\2\1</span><span class="s">"</span><span class="p">)),</span><span class="n">_</span><span class="p">[</span><span class="n">_____</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">][</span><span class="n">______</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="o">*</span><span class="mi">4</span><span class="o">-</span><span class="n">_________</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">_</span><span class="p">[</span><span class="n">_____</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">][</span><span class="n">______</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="o">*</span><span class="mi">4</span><span class="o">-</span><span class="n">_________</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">_</span><span class="p">[</span><span class="n">_____</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">______</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="o">*</span><span class="mi">4</span><span class="o">-</span><span class="n">_________</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span><span class="n">_</span><span class="p">[</span><span class="n">_____</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">______</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">_______</span><span class="o">*</span><span class="mi">4</span><span class="o">-</span><span class="n">_________</span><span class="p">[</span><span class="mi">3</span><span class="p">]))),((</span><span class="n">_______</span><span class="o">></span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">)</span><span class="o">&&</span><span class="n">printf</span><span class="p">(</span><span class="n">________</span><span class="o">%</span><span class="n">___</span><span class="o">?</span><span class="s">"%4d"</span><span class="o">:</span><span class="s">"%4d</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span><span class="n">_</span><span class="p">[(</span><span class="n">________</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="n">___</span><span class="p">][(</span><span class="n">________</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">___</span><span class="p">]))),((</span><span class="n">___</span><span class="o">&</span><span class="mi">1</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o">++</span><span class="p">)),(</span><span class="o">!</span><span class="p">(</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o">++</span><span class="p">)),(((</span><span class="n">___</span><span class="o">&</span><span class="mi">3</span><span class="p">)</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">_______</span><span class="o">++</span><span class="p">),((</span><span class="n">_______</span><span class="o">></span><span class="n">___</span><span class="o">*</span><span class="n">___</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span><span class="n">________</span><span class="o">++</span><span class="p">))),</span><span class="n">main</span><span class="p">(</span><span class="mi">0</span><span class="p">))));}</span>
</code></pre></div></div>
<p>看不懂?嗯,我也看不懂当时是怎么写的了 >_< 。不过确实是能跑的,测试如下:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Enter n(n>0): 3
8 1 6
3 5 7
4 9 2
Enter n(n>0): 4
1 15 14 4
12 6 7 9
8 10 11 5
13 3 2 16
Enter n(n>0): 5
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Enter n(n>0): 6
32 29 136 133 24 21
30 31 134 135 22 23
12 9 137 140 28 25
10 11 138 139 26 27
13 16 144 141 5 8
14 15 142 143 6 7
</code></pre></div></div>
搭建 Google Fonts 加速代理
https://pxx.io/2014/08/19/google-fonts-proxy
2014-08-19T00:00:00+08:00
<p>Google Fonts 提供了十分丰富的在线字体,用的人很多。但在国内,由于众所周知的原因不方便使用。解决方案一般是把字体下载到本地,或使用大(3)数(6)字(0)的 Google Fonts 代理(不支持 HTTPS)。为了支持 HTTPS,可以在国外的 VPS 上配置 Nginx 反向代理 Google Fonts。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="配置">配置</h2>
<p>Nginx 的配置如下:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">location</span> <span class="n">/google/fonts/</span> <span class="p">{</span>
<span class="kn">sub_filter_types</span> <span class="nc">text/css</span><span class="p">;</span>
<span class="kn">sub_filter_once</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">sub_filter</span> <span class="n">//fonts.gstatic.com/</span> <span class="n">//cdn.pxx.io/google/fonts-static/</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/google/fonts/(.+)</span>$ <span class="n">/</span><span class="nv">$1</span> <span class="s">break</span><span class="p">;</span>
<span class="kn">proxy_pass</span> <span class="s">https://fonts.googleapis.com</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="s">"fonts.googleapis.com"</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Accept-Encoding</span> <span class="s">""</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">location</span> <span class="n">/google/fonts-static/</span> <span class="p">{</span>
<span class="kn">rewrite</span> <span class="s">^/google/fonts-static/(.+)</span>$ <span class="n">/</span><span class="nv">$1</span> <span class="s">break</span><span class="p">;</span>
<span class="kn">proxy_pass</span> <span class="s">https://fonts.gstatic.com</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="s">"fonts.gstatic.com"</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Accept-Encoding</span> <span class="s">""</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>可以根据需要自行设置 proxy_cache。</p>
<h2 id="使用">使用</h2>
<p>用法很简单,只要把 <code class="highlighter-rouge">fonts.googleapis.com</code> 全部换成 <code class="highlighter-rouge">cdn.pxx.io/google/fonts</code> 即可。例如,本博客使用的 Clicker Script 字体:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><link</span> <span class="na">rel=</span><span class="s">'stylesheet'</span> <span class="na">type=</span><span class="s">'text/css'</span> <span class="na">href=</span><span class="s">"//cdn.pxx.io/google/fonts/css?family=Clicker+Script"</span><span class="nt">></span>
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="https://sskaje.me/2014/01/nginx-proxy-google-urls-wordpress/#.U_NrZI-Sy00">Nginx proxy for Google URLs in WordPress</a></li>
<li><a href="http://nginx.org/en/docs/http/ngx_http_sub_module.html">Module ngx_http_sub_module</a></li>
</ol>
Bind 搭建智能 DNS
https://pxx.io/2014/08/15/smart-dns
2014-08-15T00:00:00+08:00
<p>智能 DNS 是指权威 DNS 服务器根据查询的来源 IP 地址选择不同的记录,常用于 CDN 或负载均衡。例如,查询的 IP 来自电信时,返回电信线路服务器的 IP 地址;查询的 IP 来自联通时,返回联通线路服务器的 IP 地址。利用 Bind 的 View 功能和搜集到的各运营商的 IP 地址段,即可实现简单的智能 DNS。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="搜集各运营商的-ip-地址段">搜集各运营商的 IP 地址段</h2>
<p>编写了一些 Bash 脚本来自动搜集,代码见:<a href="https://gitcafe.com/XiaoxiaoPu/ip-db">https://gitcafe.com/XiaoxiaoPu/ip-db</a>,脚本还会生成直接供 Bind 使用的 ACL 配置。</p>
<pre><code class="language-bind">acl cn_cmcc {
36.128.0.0/10;
39.128.0.0/10;
103.20.112.0/22;
103.21.176.0/22;
111.0.0.0/10;
112.0.0.0/10;
......
221.129.0.0/16;
223.4.0.0/14;
2001:e80::/32;
2400:d200::/32;
2409:8000::/20;
};
</code></pre>
<h2 id="配置-bind">配置 Bind</h2>
<p>配置文件中主要修改的部分如下:</p>
<pre><code class="language-bind">include "cn_cmcc.acl";
include "cn_cernet.acl";
include "cn_unicom.acl";
include "cn_chinanet.acl";
include "cn_unknown.acl";
view cn_cmcc {
match-clients { cn_cmcc; };
zone "example.com." {
type master;
file "example.com.cn_cmcc.zone";
};
};
view cn_cernet {
match-clients { cn_cernet; };
zone "example.com." {
type master;
file "example.com.cn_cernet.zone";
};
};
view cn_unicom {
match-clients { cn_unicom; };
zone "example.com." {
type master;
file "example.com.cn_unicom.zone";
};
};
view cn_chinanet {
match-clients { cn_chinanet; };
zone "example.com." {
type master;
file "example.com.cn_chinanet.zone";
};
};
view cn_unknown {
match-clients { cn_unknown; };
zone "example.com." {
type master;
file "example.com.cn_unknown.zone";
};
};
view any {
match-clients { any; };
zone "example.com." {
type master;
file "example.com.any.zone";
};
};
</code></pre>
<p>然后分别编写适合各个运营商线路的 Zone,重启 Bind 即可。</p>
<h2 id="测试">测试</h2>
<h3 id="电信联通教育网">电信/联通/教育网</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @202.102.213.68 +nocomments patme.net
<span class="p">;</span> <<<span class="o">>></span> DiG 9.9.2-P2 <<<span class="o">>></span> @202.102.213.68 +nocomments patme.net
<span class="p">;</span> <span class="o">(</span>1 server found<span class="o">)</span>
<span class="p">;;</span> global options: +cmd
<span class="p">;</span>patme.net. IN A
patme.net. 7200 IN A 202.141.160.99
patme.net. 600 IN NS ns1.patme.net.
patme.net. 600 IN NS ns2.patme.net.
ns1.patme.net. 600 IN AAAA 2001:da8:d800:71::205
ns2.patme.net. 600 IN AAAA 2605:f700:40:c00::d5e7:4da6
<span class="p">;;</span> Query <span class="nb">time</span>: 25 msec
<span class="p">;;</span> SERVER: 202.102.213.68#53<span class="o">(</span>202.102.213.68<span class="o">)</span>
<span class="p">;;</span> WHEN: Fri Aug 15 23:48:35 2014
<span class="p">;;</span> MSG SIZE rcvd: 146
</code></pre></div></div>
<h3 id="移动">移动</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @211.138.164.6 +nocomments patme.net
<span class="p">;</span> <<<span class="o">>></span> DiG 9.9.2-P2 <<<span class="o">>></span> @211.138.164.6 +nocomments patme.net
<span class="p">;</span> <span class="o">(</span>1 server found<span class="o">)</span>
<span class="p">;;</span> global options: +cmd
<span class="p">;</span>patme.net. IN A
patme.net. 1778 IN A 202.141.176.99
patme.net. 578 IN NS ns1.patme.net.
patme.net. 578 IN NS ns2.patme.net.
ns1.patme.net. 578 IN AAAA 2001:da8:d800:71::205
ns2.patme.net. 578 IN AAAA 2605:f700:40:c00::d5e7:4da6
<span class="p">;;</span> Query <span class="nb">time</span>: 66 msec
<span class="p">;;</span> SERVER: 211.138.164.6#53<span class="o">(</span>211.138.164.6<span class="o">)</span>
<span class="p">;;</span> WHEN: Fri Aug 15 23:51:30 2014
<span class="p">;;</span> MSG SIZE rcvd: 146
</code></pre></div></div>
<h3 id="国外">国外</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @8.8.8.8 +nocomments patme.net
<span class="p">;</span> <<<span class="o">>></span> DiG 9.9.2-P2 <<<span class="o">>></span> @8.8.8.8 +nocomments patme.net
<span class="p">;</span> <span class="o">(</span>1 server found<span class="o">)</span>
<span class="p">;;</span> global options: +cmd
<span class="p">;</span>patme.net. IN A
patme.net. 599 IN A 192.157.213.104
<span class="p">;;</span> Query <span class="nb">time</span>: 3263 msec
<span class="p">;;</span> SERVER: 8.8.8.8#53<span class="o">(</span>8.8.8.8<span class="o">)</span>
<span class="p">;;</span> WHEN: Fri Aug 15 23:52:37 2014
<span class="p">;;</span> MSG SIZE rcvd: 54
</code></pre></div></div>
<p>测试成功,对来自不同运营商线路的 DNS 查询确实返回了不同的 IP 地址,智能 DNS 就搭建好了。</p>
CentOS处理 .rpmnew 和 .rpmsave 文件
https://pxx.io/2014/08/07/centos-rpmnew-rpmsave
2014-08-07T00:00:00+08:00
<p>在升级软件包时,有时不同版本间的配置文件可能会不太兼容。RPM使用 <code class="highlighter-rouge">.rpmnew</code> 和 <code class="highlighter-rouge">.rpmsave</code> 来处理这种情况。有时,新版本的配置文件会保存为 <code class="highlighter-rouge">.rpmnew</code>;有时,会把老版本的配置文件保存为 <code class="highlighter-rouge">.rpmsave</code>。</p>
<!--more-->
<p><a id="more"></a></p>
<p>处理 <code class="highlighter-rouge">.rpmnew</code> 和 <code class="highlighter-rouge">.rpmsave</code> 文件的方法为:</p>
<ol>
<li>比较新旧配置文件的不同</li>
<li>参照新的配置文件手动修改</li>
<li>删除旧的配置文件</li>
</ol>
<p>下面举例说明具体步骤。</p>
<h3 id="查找-rpmnew-和-rpmsave-文件">查找 <code class="highlighter-rouge">.rpmnew</code> 和 <code class="highlighter-rouge">.rpmsave</code> 文件</h3>
<p>以 <code class="highlighter-rouge">root</code> 权限执行下面的命令,查询系统中所有的 <code class="highlighter-rouge">.rpmnew</code> 和 <code class="highlighter-rouge">.rpmsave</code> 文件:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>tmp <span class="k">in</span> <span class="si">$(</span>find /etc /var <span class="nt">-name</span> <span class="s1">'*.rpm?*'</span><span class="si">)</span><span class="p">;</span> <span class="k">do </span><span class="nb">echo</span> <span class="nv">$tmp</span><span class="p">;</span> <span class="k">done</span>
</code></pre></div></div>
<p>执行结果为:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/php-fpm.d/www.conf.rpmnew
/etc/sysconfig/saslauthd.rpmsave
/var/lib/rpm/.rpm.lock
</code></pre></div></div>
<h3 id="比较新旧配置文件">比较新旧配置文件</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /etc/php-fpm.d/
diff <span class="nt">-aur</span> www.conf<span class="o">{</span>,.rpmnew<span class="o">}</span>
</code></pre></div></div>
<p>结果如下:</p>
<div class="language-diff highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gd">--- www.conf 2014-07-01 02:57:14.956961608 +0800
</span><span class="gi">+++ www.conf.rpmnew 2014-07-16 17:14:47.000000000 +0800
</span><span class="p">@@ -9,7 +9,7 @@</span>
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
<span class="gd">-listen = /var/run/php-fpm/php-fpm.sock
</span><span class="gi">+listen = 127.0.0.1:9000
</span>
; Set listen(2) backlog. A value of '-1' means unlimited.
; Default Value: -1
<span class="p">@@ -21,24 +21,24 @@</span>
; must be separated by a comma. If this value is left blank, connections will be
; accepted from any ip address.
; Default Value: any
<span class="gd">-;listen.allowed_clients = 127.0.0.1
</span><span class="gi">+listen.allowed_clients = 127.0.0.1
</span>
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
<span class="gd">-; mode is set to 0666
-listen.owner = nginx
-listen.group = nginx
-listen.mode = 0660
</span><span class="gi">+; mode is set to 0660
+;listen.owner = nobody
+;listen.group = nobody
+;listen.mode = 0660
</span>
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
; RPM: apache Choosed to be able to access some dir as httpd
<span class="gd">-user = nginx
</span><span class="gi">+user = apache
</span> ; RPM: Keep a group allowed to write in log dir.
<span class="gd">-group = nginx
</span><span class="gi">+group = apache
</span>
; Choose how the process manager will control the number of child processes.
; Possible Values:
<span class="p">@@ -67,22 +67,22 @@</span>
; CGI.
; Note: Used when pm is set to either 'static' or 'dynamic'
; Note: This value is mandatory.
<span class="gd">-pm.max_children = 64
</span><span class="gi">+pm.max_children = 50
</span>
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
<span class="gd">-pm.start_servers = 8
</span><span class="gi">+pm.start_servers = 5
</span>
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
<span class="gd">-pm.min_spare_servers = 8
</span><span class="gi">+pm.min_spare_servers = 5
</span>
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
<span class="gd">-pm.max_spare_servers = 32
</span><span class="gi">+pm.max_spare_servers = 35
</span>
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
<span class="p">@@ -222,5 +222,6 @@</span>
; Set session path to a directory owned by process user
php_value[session.save_handler] = files
<span class="gd">-php_value[session.save_path] = /var/lib/php/session
</span><span class="gi">+php_value[session.save_path] = /var/lib/php/session
+php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
</span></code></pre></div></div>
<h3 id="处理">处理</h3>
<p>可以看出,大部分不同之处都是之前对 <code class="highlighter-rouge">/etc/php-fpm.d/www.conf</code> 做的修改,新的配置文件只是增加了<code class="highlighter-rouge">php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache</code>,那么把这一行添加到旧的配置文件中就行了</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s1">'php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache'</span> <span class="o">>></span> www.conf
<span class="nb">rm </span>www.conf.pacnew
service php-fpm restart
</code></pre></div></div>
CentOS 安装 MariaDB
https://pxx.io/2014/08/07/centos-mariadb
2014-08-07T00:00:00+08:00
<p><a href="https://mariadb.org/">MariaDB</a> 是 MySQL 的一个开源实现。在 Arch Linux 中,MariaDB 已经替代了 MySQL,所以打算在 CentOS 中也使用 MariaDB 替换 MySQL。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="添加-mariadb-yum-仓库">添加 MariaDB YUM 仓库</h2>
<p>MariaDB 官网有一个在线 <a href="https://downloads.mariadb.org/mariadb/repositories/">repository generator</a>,在该页面选择 CentOS 6(64 bit),版本选择10.1:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># MariaDB 10.1 CentOS repository list - created 2014-08-07 04:47 UTC
# http://mariadb.org/mariadb/repositories/
</span><span class="nn">[mariadb]</span>
<span class="py">name</span> <span class="p">=</span> <span class="s">MariaDB</span>
<span class="py">baseurl</span> <span class="p">=</span> <span class="s">http://yum.mariadb.org/10.1/centos6-amd64</span>
<span class="py">gpgkey</span><span class="p">=</span><span class="s">https://yum.mariadb.org/RPM-GPG-KEY-MariaDB</span>
<span class="py">gpgcheck</span><span class="p">=</span><span class="s">1</span>
</code></pre></div></div>
<p>保存到<code class="highlighter-rouge">/etc/yum.repos.d/mariadb.repo</code></p>
<h2 id="安装-mariadb">安装 MariaDB</h2>
<p>执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>MariaDB-server Mariadb-client
</code></pre></div></div>
<h2 id="配置">配置</h2>
<p>执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service mysql start
mysql_secure_installation
<span class="nb">sudo </span>service mysql restart
</code></pre></div></div>
用 linux-dash 监控服务器状态
https://pxx.io/2014/07/01/linux-dash
2014-07-01T00:00:00+08:00
<p><a href="http://www.linuxdash.com/">linux-dash</a> 是一个轻量级的 Linux 服务器 Web 监控面板,可以监视 CPU、内存、负载、网络、磁盘等系统状况。linux-dash 使用 PHP 开发,只需要 PHP+Web 服务器(如 Apache2 或 Nginx)即可运行。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="配置-nginx-和-php">配置 Nginx 和 PHP</h2>
<p>具体步骤见:<a href="/2014/06/27/centos-lnmp.html">CentOS 搭建 LNMP 环境</a>,可以不安装 MySQL。</p>
<h2 id="下载-linux-dash">下载 linux-dash</h2>
<p>linux-dash 的代码托管在 GitHub 上,可以用 <code class="highlighter-rouge">git</code> 获取:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /path/to/www/
git clone https://github.com/afaqurk/linux-dash.git linux-dash
</code></pre></div></div>
<h2 id="配置-nginx">配置 Nginx</h2>
<p>Nginx 配置文件如下:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">localhost</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path/to/www/linux-dash/</span><span class="p">;</span>
<span class="kn">charset</span> <span class="s">utf-8</span><span class="p">;</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">index</span> <span class="s">index.html</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php$</span> <span class="p">{</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php-fpm/php-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$fastcgi_script_name</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>重启 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># CentOS 6/Debian</span>
<span class="nb">sudo </span>service nginx restart
<span class="c"># Archlinux</span>
<span class="nb">sudo </span>systemctl restart nginx
</code></pre></div></div>
<p>到此就设置好了,在浏览器中访问应能看到下面的界面:</p>
<p><img style="max-width: 790px;" src="/images/linux-dash/linux-dash.png" alt="linux-dash.png" /></p>
<h2 id="开启简单的认证">开启简单的认证</h2>
<p>linux-dash 会暴漏许多系统重要信息,做好能限制别人访问。可以使用 Nginx 自带的认证功能实现。</p>
<p>生成密码文件:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>htpasswd <span class="nt">-b</span> <span class="nt">-c</span> /etc/nginx/htpasswd username password
</code></pre></div></div>
<p>然后在 Nginx 的 Server 配置块中加上:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auth_basic</span> <span class="s">"Please</span> <span class="s">Login"</span><span class="p">;</span>
<span class="k">auth_basic_user_file</span> <span class="s">htpasswd</span><span class="p">;</span>
</code></pre></div></div>
<p>重启 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># CentOS 6/Debian</span>
<span class="nb">sudo </span>service nginx restart
<span class="c"># Archlinux</span>
<span class="nb">sudo </span>systemctl restart nginx
</code></pre></div></div>
CentOS 升级 PHP
https://pxx.io/2014/06/28/centos-upgrade-php
2014-06-28T00:00:00+08:00
<p>CentOS 官方仓库的 PHP 是 5.3.3,而 ownCloud 要求最低版本是 5.3.8,因此需要升级 PHP。添 REMI 源后即可升级到较新版本的 PHP。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="添加-remi-源">添加 REMI 源</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget http://rpms.famillecollet.com/enterprise/remi.repo
<span class="nb">sudo cp </span>remi.repo /etc/yum.repos.d/
</code></pre></div></div>
<h2 id="更新">更新</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nt">--enablerepo</span><span class="o">=</span>remi update
</code></pre></div></div>
<p>之后就会提醒 PHP 可以更新了,执行更新即可。</p>
<p>然后重启 <code class="highlighter-rouge">php-fpm</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service php-fpm restart
</code></pre></div></div>
在 CentOS 上搭建 ownCloud 私人云存储
https://pxx.io/2014/06/28/centos-owncloud
2014-06-28T00:00:00+08:00
<p>之前在 Debian 服务器上搭建了<a href="http://owncloud.org">ownCloud</a>,下面在 CentOS 上做一遍,步骤稍有不同。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="配置-lnmp">配置 LNMP</h2>
<p>具体步骤见:<a href="/2014/06/27/centos-lnmp.html">CentOS 搭建 LNMP 环境</a></p>
<h2 id="安装依赖的-php-模块">安装依赖的 PHP 模块</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>php-gd php-mbstring php-pear-MDB2-Driver-mysqli php-pear-Net-Curl php-process php-xml php-zipstream php-intl php-mcrypt php-pecl-imagick
</code></pre></div></div>
<h2 id="下载并解压-owncloud">下载并解压 ownCloud</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://download.owncloud.org/community/owncloud-6.1.0.tar.bz2
<span class="nb">tar</span> <span class="nt">-jxf</span> owncloud-6.1.0.tar.bz2
<span class="nb">cp</span> <span class="nt">-r</span> owncloud/<span class="k">*</span> /path/to/your/webservers/document-root
</code></pre></div></div>
<p>记得修改文件权限:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /path/to/your/webservers/document-root/
<span class="nb">mkdir </span>data tmp
<span class="nb">sudo chown</span> <span class="nt">-R</span> nginx:nginx config data apps tmp
</code></pre></div></div>
<h2 id="配置-nginx">配置 Nginx</h2>
<p>按照官方安装文档上的说明编辑 Nginx 的 server 配置块:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">cloud.example.com</span><span class="p">;</span>
<span class="kn">ssl_certificate</span> <span class="n">/etc/ssl/nginx/cloud.example.com.crt</span><span class="p">;</span>
<span class="kn">ssl_certificate_key</span> <span class="n">/etc/ssl/nginx/cloud.example.com.key</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/var/www/</span><span class="p">;</span>
<span class="kn">client_max_body_size</span> <span class="mi">10G</span><span class="p">;</span> <span class="c1"># set max upload size
</span> <span class="kn">fastcgi_buffers</span> <span class="mi">64</span> <span class="mi">4K</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/caldav(.*)</span>$ <span class="n">/remote.php/caldav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/carddav(.*)</span>$ <span class="n">/remote.php/carddav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/webdav(.*)</span>$ <span class="n">/remote.php/webdav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">error_page</span> <span class="mi">403</span> <span class="n">/core/templates/403.php</span><span class="p">;</span>
<span class="kn">error_page</span> <span class="mi">404</span> <span class="n">/core/templates/404.php</span><span class="p">;</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/robots.txt</span> <span class="p">{</span>
<span class="kn">allow</span> <span class="s">all</span><span class="p">;</span>
<span class="kn">log_not_found</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(data|config|\.ht|db_structure\.xml|README)</span> <span class="p">{</span>
<span class="kn">deny</span> <span class="s">all</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="c1"># The following 2 rules are only needed with webfinger
</span> <span class="kn">rewrite</span> <span class="s">^/.well-known/host-meta</span> <span class="n">/public.php?service=host-meta</span> <span class="s">last</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/host-meta.json</span> <span class="n">/public.php?service=host-meta-json</span> <span class="s">last</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/carddav</span> <span class="n">/remote.php/carddav/</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/caldav</span> <span class="n">/remote.php/caldav/</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^(/core/doc/[^</span><span class="err">\</span><span class="n">/]+/</span><span class="s">)</span>$ <span class="nv">$1</span><span class="n">/index.html</span><span class="p">;</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^(.+?\.php)(/.*)?$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$1</span> <span class="p">=</span> <span class="mi">404</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$1</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">PATH_INFO</span> <span class="nv">$2</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">HTTPS</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php-fpm/php-fpm.sock</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Optional: set long EXPIRES header on static assets
</span> <span class="kn">location</span> <span class="p">~</span><span class="sr">*</span> <span class="s">^.+</span><span class="err">\</span><span class="s">.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)</span>$ <span class="p">{</span>
<span class="kn">expires</span> <span class="s">30d</span><span class="p">;</span>
<span class="c1"># Optional: Don't log access to assets
</span> <span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>然后重启 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service nginx restart
</code></pre></div></div>
<h2 id="配置-mysql">配置 MySQL</h2>
<p>登陆 MySQL:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql <span class="nt">-u</span> root <span class="nt">-p</span>
</code></pre></div></div>
<p>创建用户<code class="highlighter-rouge">cloud</code>:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">create</span> <span class="k">user</span> <span class="s1">'cloud'</span><span class="o">@</span><span class="s1">'localhost'</span> <span class="n">identified</span> <span class="k">by</span> <span class="s1">'password'</span><span class="p">;</span>
</code></pre></div></div>
<p>创建数据库 <code class="highlighter-rouge">cloud</code>,并授权用户 <code class="highlighter-rouge">cloud</code> 拥有此数据库的所有权限:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">create</span> <span class="k">database</span> <span class="n">cloud</span><span class="p">;</span>
<span class="k">grant</span> <span class="k">all</span> <span class="k">privileges</span> <span class="k">on</span> <span class="n">cloud</span><span class="p">.</span><span class="o">*</span> <span class="k">to</span> <span class="s1">'cloud'</span><span class="o">@</span><span class="s1">'localhost'</span> <span class="n">identified</span> <span class="k">by</span> <span class="s1">'passwd'</span><span class="p">;</span>
<span class="n">flush</span> <span class="k">privileges</span><span class="p">;</span>
</code></pre></div></div>
<h2 id="进入-owncloud-安装界面">进入 ownCloud 安装界面</h2>
<p>在浏览器中打开 <a href="https://yourdomain.com/">https://yourdomain.com/</a>,即可进入 ownCloud 的安装界面。</p>
<p>首先需要建立一个管理员账号,输入用户名和密码即可。点击<code class="highlighter-rouge">高级</code>,可以看到数据库配置选项,选择 MySQL,数据库名填 <code class="highlighter-rouge">cloud</code>,用户名填 <code class="highlighter-rouge">cloud</code>,密码填刚才设定的密码。最后点 <code class="highlighter-rouge">Finish</code> 完成安装过程</p>
<h2 id="修改上传限制">修改上传限制</h2>
<p>默认上传文件最大为 2M,显然太小了,下面改成 1024M。</p>
<p>编辑 <code class="highlighter-rouge">/etc/php5/fpm/php.ini</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">upload_tmp_dir</span> <span class="p">=</span> <span class="s">/path/to/your/webservers/document-root/tmp</span>
<span class="py">upload_max_filesize</span> <span class="p">=</span> <span class="s">1024M</span>
<span class="py">post_max_size</span> <span class="p">=</span> <span class="s">1024M</span>
</code></pre></div></div>
<p>然后重启 <code class="highlighter-rouge">php-fpm</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service php-fpm restart
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://doc.owncloud.org/server/6.0/admin_manual/installation/installation_source.html">ownCloud Administractors Manual: Manual Install</a></li>
</ol>
在 CentOS 上安装 Jekyll
https://pxx.io/2014/06/28/centos-jekyll
2014-06-28T00:00:00+08:00
<p><a href="http://jekyllrb.com/">Jekyll</a> 是用 <a href="https://www.ruby-lang.org/">Ruby</a> 编写的静态网站框架,十分流行。本文记录了在 CentOS 上安装配置 Jekyll 的过程。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-ruby">安装 Ruby</h2>
<p>CentOS 6.5 的 <code class="highlighter-rouge">ruby</code> 版本太低,因此需要用 <code class="highlighter-rouge">rvm</code> 安装最新版本。</p>
<p>安装 <code class="highlighter-rouge">rvm</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gpg <span class="nt">--keyserver</span> hkp://keys.gnupg.net <span class="nt">--recv-keys</span> 409B6B1796C275462A1703113804BB82D39DC0E3
curl <span class="nt">-sSL</span> https://get.rvm.io | bash <span class="nt">-s</span> stable
</code></pre></div></div>
<p>安装 Ruby 2.2.1:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>libyaml
rvm <span class="nb">install </span>2.1.2
</code></pre></div></div>
<p>设为默认版本:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rvm use 2.1.2 <span class="nt">--default</span>
</code></pre></div></div>
<p>修改 <code class="highlighter-rouge">gem</code> 源:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem sources <span class="nt">--remove</span> https://rubygems.org/
gem sources <span class="nt">-a</span> http://mirrors.ustc.edu.cn/rubygems/
</code></pre></div></div>
<h2 id="安装-jekyll">安装 Jekyll</h2>
<p>使用<code class="highlighter-rouge">gem</code>安装:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem <span class="nb">install </span>jekyll
</code></pre></div></div>
<p><code class="highlighter-rouge">jekyll</code> 依赖 JavaScript 运行时库,安装 <code class="highlighter-rouge">nodejs</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>nodejs
</code></pre></div></div>
<h2 id="测试">测试</h2>
<p>运行下面的命令测试 Jekyll 能否正常工作:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll new myblog
<span class="nb">cd </span>myblog
jekyll serve
</code></pre></div></div>
<p>然后在浏览器中打开<a href="http://localhost:4000">http://localhost:4000</a>,应能看到 Jekyll 默认页面。</p>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://jekyllrb.com/docs/quickstart/">Jekyll quick-start guide</a></li>
</ol>
CentOS 搭建 LNMP 环境
https://pxx.io/2014/06/27/centos-lnmp
2014-06-27T00:00:00+08:00
<p>之前介绍了如何<a href="/2014/05/25/arch-lnmp.html">在 Arch Linux 下搭建 LNMP 环境</a>,本文介绍如何在 CentOS 下搭建 LNMP,大部分步骤是类似的。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-nginx">安装 Nginx</h2>
<p>编辑<code class="highlighter-rouge">/etc/yum.repos.d/nginx.repo</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[nginx]</span>
<span class="py">name</span><span class="p">=</span><span class="s">nginx repo</span>
<span class="py">baseurl</span><span class="p">=</span><span class="s">http://nginx.org/packages/centos/$releasever/$basearch/</span>
<span class="py">gpgcheck</span><span class="p">=</span><span class="s">0</span>
<span class="py">enabled</span><span class="p">=</span><span class="s">1</span>
</code></pre></div></div>
<p>然后执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum update
<span class="nb">sudo </span>yum <span class="nb">install </span>nginx
</code></pre></div></div>
<h2 id="安装-mysql">安装 MySQL</h2>
<p>执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>mysql mysql-server
</code></pre></div></div>
<p>启动MySQL,设置数据库<code class="highlighter-rouge">root</code>账户密码:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service mysqld start
mysql_secure_installation
<span class="nb">sudo </span>service mysqld restart
</code></pre></div></div>
<p>如果要用 MariaDB 替换 MySQL,可参考此文配置:<a href="/2014/08/07/centos-mariadb.html">CentOS 安装 MariaDB</a></p>
<h2 id="安装-php">安装 PHP</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>php php-fpm
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/php-fpm.d/www.conf</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">listen</span> <span class="p">=</span> <span class="s">/var/run/php-fpm/php-fpm.sock</span>
<span class="py">listen.owner</span> <span class="p">=</span> <span class="s">nginx</span>
<span class="py">listen.group</span> <span class="p">=</span> <span class="s">nginx</span>
<span class="py">listen.mode</span> <span class="p">=</span> <span class="s">0660</span>
<span class="py">user</span> <span class="p">=</span> <span class="s">nginx</span>
<span class="py">group</span> <span class="p">=</span> <span class="s">nginx</span>
</code></pre></div></div>
<p>修改 <code class="highlighter-rouge">/var/lib/php/session/</code>的拥有者:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo chown </span>nginx:nginx <span class="nt">-R</span> /var/lib/php/session/
</code></pre></div></div>
<p>重启 <code class="highlighter-rouge">php-fpm</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service php-fpm restart
</code></pre></div></div>
<h2 id="在-nginx-中启用-php">在 Nginx 中启用 PHP</h2>
<p>编辑 Nginx 的 server 配置块:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">localhost</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/usr/share/nginx/html</span><span class="p">;</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php$</span> <span class="p">{</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php-fpm/php-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$fastcgi_script_name</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="测试-php">测试 PHP</h2>
<p>在 Web 根目录中新建 <code class="highlighter-rouge">index.php</code>:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?php</span>
<span class="nb">phpinfo</span><span class="p">();</span>
<span class="cp">?></span>
</code></pre></div></div>
<p>这时在浏览器中打开 <a href="http://127.0.0.1/">http://127.0.0.1/</a> 应能看到 PHP 版本信息页面。</p>
在 Debian 上搭建 ownCloud 私人云存储
https://pxx.io/2014/06/25/debian-owncloud
2014-06-25T00:00:00+08:00
<p><a href="http://owncloud.org">ownCloud</a> 是 KDE 社区开发的私有云存储系统,可以用来搭建自己用的云盘。别人的云盘用着总会不放心,最多用来存储一些不太重要的电影什么的。自己搭建的云盘虽然仍要使用买来的 VPS,但总还是安全许多,可以用来存储私密性的文件。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="配置-lnmp">配置 LNMP</h2>
<p>具体步骤见:<a href="/2014/06/24/debian-lnmp.html">Debian 搭建 LNMP 环境</a></p>
<h2 id="安装依赖的-php-模块">安装依赖的 PHP 模块</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>php5-mysql php5-gd php-xml-parser php5-intl php5-mcrypt php5-curl php5-imagick
</code></pre></div></div>
<h2 id="下载并解压-owncloud">下载并解压 ownCloud</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://download.owncloud.org/community/owncloud-6.1.0.tar.bz2
<span class="nb">tar</span> <span class="nt">-jxf</span> owncloud-6.1.0.tar.bz2
<span class="nb">cp</span> <span class="nt">-r</span> owncloud/<span class="k">*</span> /path/to/your/webservers/document-root
</code></pre></div></div>
<p>记得修改文件权限:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /path/to/your/webservers/document-root/
<span class="nb">mkdir </span>config
<span class="nb">sudo chown</span> <span class="nt">-R</span> www-data:www-data config
<span class="nb">mkdir </span>data
<span class="nb">sudo chown</span> <span class="nt">-R</span> www-data:www-data data
<span class="nb">sudo chown</span> <span class="nt">-R</span> www-data:www-data apps
<span class="nb">mkdir </span>tmp
<span class="nb">sudo chown</span> <span class="nt">-R</span> www-data:www-data tmp
</code></pre></div></div>
<h2 id="配置-nginx">配置 Nginx</h2>
<p>按照官方安装文档上的说明编辑 Nginx 的 server 配置块:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">cloud.example.com</span><span class="p">;</span>
<span class="kn">ssl_certificate</span> <span class="n">/etc/ssl/nginx/cloud.example.com.crt</span><span class="p">;</span>
<span class="kn">ssl_certificate_key</span> <span class="n">/etc/ssl/nginx/cloud.example.com.key</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/var/www/</span><span class="p">;</span>
<span class="kn">client_max_body_size</span> <span class="mi">10G</span><span class="p">;</span> <span class="c1"># set max upload size
</span> <span class="kn">fastcgi_buffers</span> <span class="mi">64</span> <span class="mi">4K</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/caldav(.*)</span>$ <span class="n">/remote.php/caldav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/carddav(.*)</span>$ <span class="n">/remote.php/carddav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/webdav(.*)</span>$ <span class="n">/remote.php/webdav</span><span class="nv">$1</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">error_page</span> <span class="mi">403</span> <span class="n">/core/templates/403.php</span><span class="p">;</span>
<span class="kn">error_page</span> <span class="mi">404</span> <span class="n">/core/templates/404.php</span><span class="p">;</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/robots.txt</span> <span class="p">{</span>
<span class="kn">allow</span> <span class="s">all</span><span class="p">;</span>
<span class="kn">log_not_found</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(data|config|\.ht|db_structure\.xml|README)</span> <span class="p">{</span>
<span class="kn">deny</span> <span class="s">all</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="c1"># The following 2 rules are only needed with webfinger
</span> <span class="kn">rewrite</span> <span class="s">^/.well-known/host-meta</span> <span class="n">/public.php?service=host-meta</span> <span class="s">last</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/host-meta.json</span> <span class="n">/public.php?service=host-meta-json</span> <span class="s">last</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/carddav</span> <span class="n">/remote.php/carddav/</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/.well-known/caldav</span> <span class="n">/remote.php/caldav/</span> <span class="s">redirect</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^(/core/doc/[^</span><span class="err">\</span><span class="n">/]+/</span><span class="s">)</span>$ <span class="nv">$1</span><span class="n">/index.html</span><span class="p">;</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^(.+?\.php)(/.*)?$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$1</span> <span class="p">=</span> <span class="mi">404</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$1</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">PATH_INFO</span> <span class="nv">$2</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">HTTPS</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">fastcgi_pass</span> <span class="s">php-handler</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Optional: set long EXPIRES header on static assets
</span> <span class="kn">location</span> <span class="p">~</span><span class="sr">*</span> <span class="s">^.+</span><span class="err">\</span><span class="s">.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)</span>$ <span class="p">{</span>
<span class="kn">expires</span> <span class="s">30d</span><span class="p">;</span>
<span class="c1"># Optional: Don't log access to assets
</span> <span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>然后重启 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service nginx restart
</code></pre></div></div>
<h2 id="进入-owncloud-安装界面">进入 ownCloud 安装界面</h2>
<p>在浏览器中打开 <a href="https://yourdomain.com/">https://yourdomain.com/</a>,即可进入 ownCloud 的安装界面。</p>
<p>首先需要建立一个管理员账号,输入用户名和密码即可。点击<code class="highlighter-rouge">高级</code>,可以看到数据库配置选项,选择 MySQL,然后输入 MySQL 的数据库名、用户名和密码。最后点 <code class="highlighter-rouge">Finish</code> 完成安装过程</p>
<h2 id="修改上传限制">修改上传限制</h2>
<p>默认上传文件最大为 2M,显然太小了,下面改成 512M。</p>
<p>编辑 <code class="highlighter-rouge">/etc/php5/fpm/php.ini</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">upload_tmp_dir</span> <span class="p">=</span> <span class="s">/path/to/your/webservers/document-root/tmp</span>
<span class="py">upload_max_filesize</span> <span class="p">=</span> <span class="s">512M</span>
<span class="py">post_max_size</span> <span class="p">=</span> <span class="s">512M</span>
</code></pre></div></div>
<p>然后重启 <code class="highlighter-rouge">php5-fpm</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service php5-fpm restart
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://doc.owncloud.org/server/6.0/admin_manual/installation/installation_source.html">ownCloud Administractors Manual: Manual Install</a></li>
</ol>
Nginx 配置 HTTPS 服务器
https://pxx.io/2014/06/24/nginx-https
2014-06-24T00:00:00+08:00
<p>HTTPS 是超文本传输协议和 SSL/TLS 的组合,用以提供加密通讯及对网络服务器身份的鉴定。HTTPS 可以保证客户端连接到的 Web 服务器是认证过的,连接过程是加密的,可以避免中间人攻击和窃听。下面介绍 Nginx 如何配置 HTTPS 服务器。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="获取-ssl-证书">获取 SSL 证书</h2>
<p>HTTPS 的信任继承基于预先安装在浏览器中的证书颁发机构。因此一个合法的HTTPS服务器必须从证书颁发机构处申请/购买证书。有很多证书颁发机构,大部分是要收费的,免费的有 <a href="http://www.startssl.com/">StartSLL</a>。</p>
<p>我的证书是从 StartSSL 申请的,具体过程就略过了,只要能看懂英文就没多大问题。证书申请完成后,会得到几个文件:</p>
<ul>
<li>ca.pem<br />
StartSSL 的根证书</li>
<li>sub.class1.server.ca.pem<br />
证书链</li>
<li>yourdomain.crt<br />
你自己的证书</li>
<li>yourdomain.key<br />
你自己的密钥(非常重要,必须保密)</li>
</ul>
<p>需要先合并证书链:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>ca.pem sub.class1.server.ca.pem <span class="o">>></span> yourdomain.crt
</code></pre></div></div>
<p>然后把证书复制到 <code class="highlighter-rouge">/etc/nginx/</code> 中:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo cp </span>yourdomain.crt yourdomain.key /etc/nginx/
</code></pre></div></div>
<h2 id="配置-nginx">配置 Nginx</h2>
<p>配置 HTTPS 主机,必须在 server 配置块中打开 SSL 协议,还需要指定服务器端证书和密钥文件的位置:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span><span class="p">;</span>
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">yourdomain</span><span class="p">;</span>
<span class="kn">ssl</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">ssl_certificate</span> <span class="s">yourdomain.crt</span><span class="p">;</span>
<span class="kn">ssl_certificate_key</span> <span class="s">yourdomain.key</span><span class="p">;</span>
<span class="kn">ssl_protocols</span> <span class="s">SSLv3</span> <span class="s">TLSv1</span> <span class="s">TLSv1.1</span> <span class="s">TLSv1.2</span><span class="p">;</span>
<span class="kn">ssl_ciphers</span> <span class="s">HIGH:!aNULL:!MD5</span><span class="p">;</span>
<span class="kn">ssl_prefer_server_ciphers</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">ssl_session_cache</span> <span class="s">shared:SSL:1m</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/home/user/www/yourdomain/html</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.html</span><span class="p">;</span>
<span class="kn">charset</span> <span class="s">utf-8</span><span class="p">;</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">error_page</span> <span class="mi">404</span> <span class="n">/404.html</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>有时可能需要 HTTP 自动跳转到 HTTPS,可以添加下面的 server 配置块:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">yourdomain</span><span class="p">;</span>
<span class="kn">rewrite</span> <span class="s">^/(.*)</span>$ <span class="s">https://yourdomain/</span><span class="nv">$1</span> <span class="s">permanent</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>然后重启 Nginx 即可:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Debian/CentOS 6</span>
<span class="nb">sudo </span>service nginx restart
<span class="c"># Arch Linux</span>
<span class="nb">sudo </span>systemctl restart nginx
</code></pre></div></div>
Debian 搭建 LNMP 环境
https://pxx.io/2014/06/24/debian-lnmp
2014-06-24T00:00:00+08:00
<p>之前在 <a href="/2014/05/25/arch-lnmp.html">Arch Linux 下搭建 LNMP 环境</a>,本文介绍了如何在 Debian 下搭建 LNMP,大部分步骤是类似的。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-nginx">安装 Nginx</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>nginx
</code></pre></div></div>
<h2 id="安装-mariadb">安装 MariaDB</h2>
<p>Debian Testing 已经收录了 MariaDB:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get installl mariadb-server mariadb-client
</code></pre></div></div>
<p>安装过程会询问数据库 <code class="highlighter-rouge">root</code> 用户密码。</p>
<h2 id="安装-php">安装 PHP</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>php5 php5-fpm
</code></pre></div></div>
<h2 id="在-nginx-中启用-php">在 Nginx 中启用 PHP</h2>
<p>编辑 Nginx 的 server 配置块:</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">localhost</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/usr/share/nginx/html</span><span class="p">;</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php$</span> <span class="p">{</span>
<span class="kn">fastcgi_split_path_info</span> <span class="s">^(.+</span><span class="err">\</span><span class="s">.php)(/.+)</span>$<span class="p">;</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php5-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="测试-php">测试 PHP</h2>
<p>在 Web 根目录中新建 <code class="highlighter-rouge">index.php</code>:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?php</span>
<span class="nb">phpinfo</span><span class="p">();</span>
<span class="cp">?></span>
</code></pre></div></div>
<p>这时在浏览器中打开 <a href="http://127.0.0.1/">http://127.0.0.1/</a>,应能看到PHP版本信息页面。</p>
Bind 搭建本地 DNS 缓存服务器
https://pxx.io/2014/06/22/recursive-dns-server
2014-06-22T00:00:00+08:00
<p>之前使用 <a href="/2014/05/24/dnsmasq.html">Dnsmasq 搭建本地 DNS 缓存服务器</a>,有个缺点就是必须要设置一个上级 DNS 服务器。上级 DNS 服务器选 Google 的 8.8.8.8 时,会导致一些网站(如淘宝)解析成国外 IP,导致访问速度变慢。选用国内的公共 DNS,又无法起到防止 DNS 污染的功能。改用 Bind 搭建本地 DNS 缓存可以解决这个问题,因为 Bind 可以自己从根域解析。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-bind">安装 Bind</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Arch Linux</span>
<span class="nb">sudo </span>pacman <span class="nt">-S</span> <span class="nb">bind</span>
<span class="c"># CentOS</span>
<span class="nb">sudo </span>yum <span class="nb">install bind</span>
<span class="c"># Debian</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>bind9
</code></pre></div></div>
<h2 id="启动服务">启动服务</h2>
<p>默认配置下,Bind 即是一个递归 DNS 缓存服务器,直接启动 Bind 就行了。</p>
<h3 id="arch-linux">Arch Linux</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Arch Linux</span>
<span class="nb">sudo </span>systemctl start named.service
<span class="c"># CentOS</span>
<span class="nb">sudo </span>service named start
<span class="c"># Debian/Ubuntu</span>
<span class="nb">sudo </span>service <span class="nb">bind </span>start
</code></pre></div></div>
<h2 id="测试">测试</h2>
<p>用下面的命令测试 Bind 是否正常工作</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @localhost www.google.com
</code></pre></div></div>
<p>正常的话应有类似下面的输出</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; <<>> DiG 9.9.2-P2 <<>> @localhost www.google.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20218
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 4, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 300 IN A 74.125.68.103
www.google.com. 300 IN A 74.125.68.106
www.google.com. 300 IN A 74.125.68.105
www.google.com. 300 IN A 74.125.68.99
www.google.com. 300 IN A 74.125.68.147
www.google.com. 300 IN A 74.125.68.104
;; AUTHORITY SECTION:
google.com. 166510 IN NS ns4.google.com.
google.com. 166510 IN NS ns3.google.com.
google.com. 166510 IN NS ns1.google.com.
google.com. 166510 IN NS ns2.google.com.
;; ADDITIONAL SECTION:
ns1.google.com. 166510 IN A 216.239.32.10
ns2.google.com. 166510 IN A 216.239.34.10
ns3.google.com. 166510 IN A 216.239.36.10
ns4.google.com. 166510 IN A 216.239.38.10
;; Query time: 159 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Jun 22 15:37:05 2014
;; MSG SIZE rcvd: 275
</code></pre></div></div>
<h2 id="修改系统默认-dns-服务器">修改系统默认 DNS 服务器</h2>
<h3 id="arch-linux-1">Arch Linux</h3>
<p>编辑<code class="highlighter-rouge">/etc/resolvconf.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">name_servers</span><span class="p">=</span><span class="s">127.0.0.1</span>
</code></pre></div></div>
<h3 id="centosdebianubuntu">CentOS/Debian/Ubuntu</h3>
<p>编辑<code class="highlighter-rouge">/etc/resolv.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">nameserver</span> <span class="err">127.0.0.1</span>
</code></pre></div></div>
搭建权威 DNS 服务器
https://pxx.io/2014/06/22/authority-dns-server
2014-06-22T00:00:00+08:00
<p>Bind 不仅可以用来<a href="/2014/06/22/bind.html">搭建递归 DNS 服务器</a>,也可以用来搭建权威 DNS 服务器。下面介绍如何用 Bind 搭建权威 DNS 服务器。</p>
<!--more-->
<p><a id="more"></a></p>
<h3 id="安装-bind">安装 Bind</h3>
<p>执行下面的命令安装:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Arch Linux</span>
<span class="nb">sudo </span>pacman <span class="nt">-S</span> <span class="nb">bind</span>
<span class="c"># CentOS</span>
<span class="nb">sudo </span>yum <span class="nb">install bind</span>
<span class="c"># Debian/Ubuntu</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>bind9
</code></pre></div></div>
<h3 id="配置-bind">配置 Bind</h3>
<p>编辑 <code class="highlighter-rouge">/etc/named.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>controls {
inet 127.0.0.1 allow { localhost; };
};
options {
directory "/var/named";
auth-nxdomain yes;
datasize default;
allow-query { any; };
recursion no;
version none;
hostname none;
server-id none;
listen-on { any; };
listen-on-v6 { any; };
rate-limit {
responses-per-second 100;
errors-per-second 5;
ipv4-prefix-length 32;
};
};
zone "example.com." {
type master;
file "example.com.zone";
};
</code></pre></div></div>
<p>最后编辑 <code class="highlighter-rouge">example.com.</code> 的 Zone 文件 <code class="highlighter-rouge">/var/named/example.com.zone</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$TTL 600
$ORIGIN example.com
@ IN SOA ns1.example.com. webmaster.example.com. (
2014062200
600
180
36000
600 )
@ IN NS ns1.example.com
@ IN NS ns2.example.com
ns1 IN A 192.168.1.1
ns2 IN A 192.168.1.2
@ IN MX 5 192.168.1.3
@ IN MX 10 192.168.1.4
@ IN A 192.168.1.1
www IN A 192.168.1.1
</code></pre></div></div>
<h2 id="启动-bind">启动 Bind</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Arch Linux</span>
<span class="nb">sudo </span>systemctl start named
<span class="c"># CentOS</span>
<span class="nb">sudo </span>service named start
<span class="c"># Debian/Ubuntu</span>
<span class="nb">sudo </span>service <span class="nb">bind </span>start
</code></pre></div></div>
<h2 id="测试">测试</h2>
<p>用下面的命令测试 Bind 是否正常工作,其中 <code class="highlighter-rouge">example.com</code> 替换成自己的域名</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @localhost example.com
</code></pre></div></div>
<h2 id="注册-dns-服务器">注册 DNS 服务器</h2>
<p>DNS 服务器要在域名注册商那里注册后才能真正作为权威 DNS 服务器来使用,不同域名注册商步骤不一,就不介绍了。</p>
Debian 搭建 OpenVPN 服务器
https://pxx.io/2014/06/03/debian-openvpn
2014-06-03T00:00:00+08:00
<p>OpenVPN 是一种安全可靠的 VPN 软件,本文中介绍了 Debian Testing 中 OpenVPN 的安装与配置过程。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装">安装</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>iptables easy-rsa openvpn
</code></pre></div></div>
<h2 id="准备证书和密钥">准备证书和密钥</h2>
<p>使用<code class="highlighter-rouge">easy-rsa</code>脚本来生成密钥,首先把脚本复制到当前目录中</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cp</span> <span class="nt">-r</span> /usr/share/easy-rsa ./
<span class="nb">cd </span>easy-rsa
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">vars</code>,设置KEY_COUNTRY,KEY_PROVINCE, KEY_CITY,KEY_ORG和KEY_EMAIL</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">KEY_COUNTRY</span><span class="o">=</span><span class="s2">"**"</span>
<span class="nb">export </span><span class="nv">KEY_PROVINCE</span><span class="o">=</span><span class="s2">"**"</span>
<span class="nb">export </span><span class="nv">KEY_CITY</span><span class="o">=</span><span class="s2">"**"</span>
<span class="nb">export </span><span class="nv">KEY_ORG</span><span class="o">=</span><span class="s2">"**"</span>
<span class="nb">export </span><span class="nv">KEY_EMAIL</span><span class="o">=</span><span class="s2">"**"</span>
</code></pre></div></div>
<p>执行下面的命令来创建服务器需要的证书和密钥:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">source</span> ./vars
./clean-all
./build-ca
./build-key-server server
./build-dh
</code></pre></div></div>
<p>生成的证书、密钥保存在<code class="highlighter-rouge">keys</code>中,然后复制到<code class="highlighter-rouge">/etc/openvpn/keys</code>中:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo cp</span> <span class="nt">-r</span> keys /etc/openvpn/
</code></pre></div></div>
<p><code class="highlighter-rouge">build-key</code>脚本用于创建客户端证书和密钥:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./build-key username1
./build-key username2
...
</code></pre></div></div>
<p>生成的证书和密钥发送给客户。</p>
<h2 id="配置服务器">配置服务器</h2>
<p>复制默认配置文件为<code class="highlighter-rouge">/etc/openvpn/server.conf</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo cp</span> /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
<span class="nb">sudo gunzip</span> /etc/openvpn/server.conf.gz
</code></pre></div></div>
<p>修改下面几项:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 端口号,可自定义</span>
port 1194
<span class="c"># 证书/密钥</span>
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem
server 192.168.8.0 255.255.255.0
push <span class="s2">"redirect-gateway def1 bypass-dhcp"</span>
push <span class="s2">"dhcp-option DNS 8.8.8.8"</span>
push <span class="s2">"dhcp-option DNS 8.8.4.4"</span>
</code></pre></div></div>
<p>重新启动openvpn</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service openvpn restart
</code></pre></div></div>
<p>启用IPv4转发</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>sysctl net.ipv4.ip_forward<span class="o">=</span>1
<span class="c"># net0 为WAN接口</span>
<span class="nb">sudo </span>iptables <span class="nt">-t</span> nat <span class="nt">-I</span> POSTROUTING <span class="nt">-o</span> net0 <span class="nt">-j</span> MASQUERADE
<span class="nb">sudo </span>iptables <span class="nt">-A</span> FORWARD <span class="nt">-s</span> 192.168.8.0/24 <span class="nt">-j</span> ACCEPT
<span class="nb">sudo </span>iptables <span class="nt">-A</span> FORWARD <span class="nt">-d</span> 192.168.8.0/24 <span class="nt">-j</span> ACCEPT
</code></pre></div></div>
<p>可以把这些指令添加到<code class="highlighter-rouge">/etc/rc.local</code>中以便开机自动执行。</p>
<h2 id="配置客户端">配置客户端</h2>
<p>客户端使用如下配置:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>client
dev tun
proto udp
<span class="c"># 服务器的IP和端口</span>
remote <span class="k">*</span>.<span class="k">*</span>.<span class="k">*</span>.<span class="k">*</span> 1194
resolv-retry infinite
nobind
persist-key
ping 25
ping-restart 60
<span class="c"># 客户端证书/密钥</span>
ca ca.crt
cert clientname.crt
key clientname.key
ns-cert-type server
comp-lzo
verb 3
tun-mtu 1356
</code></pre></div></div>
Debian 搭建 PPTP VPN 服务器
https://pxx.io/2014/05/28/debian-pptp-vpn
2014-05-28T00:00:00+08:00
<p>点对点隧道协议(Point to Point Tunneling Protocol)是实现虚拟专用网(VPN)的方式之一。该协议安全性不是很高,但支持比较广泛,所以在要求不高时也可以使用。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-pptpd">安装 pptpd</h2>
<p>pptpd 是 PPTP 服务器的开源实现</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>pptpd
</code></pre></div></div>
<h2 id="配置-pptpd">配置 pptpd</h2>
<p>编辑 <code class="highlighter-rouge">/etc/pptpd.conf</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">localip</span> <span class="err">192.168.7.1</span>
<span class="err">remoteip</span> <span class="err">192.168.7.2-254</span>
<span class="c">#logwtmp
</span></code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/ppp/pptpd-options</code>,修改 DNS</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">ms-dns</span> <span class="err">8.8.8.8</span>
<span class="err">ms-dns</span> <span class="err">8.8.4.4</span>
</code></pre></div></div>
<h2 id="配置-vpn-账号">配置 VPN 账号</h2>
<p>编辑 <code class="highlighter-rouge">/etc/ppp/chap-secrets</code>,添加账号、服务器名、密码和IP限制,每行一个</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">username</span> <span class="err">pptpd</span> <span class="err">password</span> <span class="err">*</span>
</code></pre></div></div>
<h2 id="配置-nat">配置 NAT</h2>
<p>启用 IPv4 转发</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>sysctl net.ipv4.ip_forward<span class="o">=</span>1
</code></pre></div></div>
<p>NAT 转发</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># net0 为WAN接口</span>
<span class="nb">sudo </span>iptables <span class="nt">-A</span> INPUT <span class="nt">-p</span> gre <span class="nt">-j</span> ACCEPT
<span class="nb">sudo </span>iptables <span class="nt">-A</span> INPUT <span class="nt">-p</span> tcp <span class="nt">-m</span> tcp <span class="nt">--dport</span> 1723 <span class="nt">-j</span> ACCEPT
<span class="nb">sudo </span>iptables <span class="nt">-t</span> nat <span class="nt">-I</span> POSTROUTING <span class="nt">-o</span> net0 <span class="nt">-j</span> MASQUERADE
<span class="nb">sudo </span>iptables <span class="nt">-A</span> FORWARD <span class="nt">-s</span> 192.168.7.0/24 <span class="nt">-j</span> ACCEPT
<span class="nb">sudo </span>iptables <span class="nt">-A</span> FORWARD <span class="nt">-d</span> 192.168.7.0/24 <span class="nt">-j</span> ACCEPT
</code></pre></div></div>
<p>可以把这些指令添加到 <code class="highlighter-rouge">/etc/rc.local</code> 中以便开机自动执行。</p>
<h2 id="重启-pptpd-服务">重启 pptpd 服务</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service pptpd restart
</code></pre></div></div>
在 Debian 上搭建自己的 Pages 服务
https://pxx.io/2014/05/26/debian-pages
2014-05-26T00:00:00+08:00
<p><a href="https://gitcafe.com">GitCafe</a> 和 <a href="https://github.com">GitHub</a> 都提供了基于 Jekyll 的 Pages 服务。用户创建特定的 Git 仓库,即可拥有自己的主页。下面在 Debian 中搭建自己的 Pages 服务。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装软件">安装软件</h2>
<h3 id="安装-git">安装 Git</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>git
</code></pre></div></div>
<h3 id="安装-jekyll">安装 Jekyll</h3>
<p>按照此文安装:<a href="/2014/05/25/debian-jekyll.html">在 Debian 上安装 Jekyll</a></p>
<h3 id="安装-ssh-server">安装 SSH Server</h3>
<p>安装 SSH Server 是为了能够远程访问 Debian 上的 Git 仓库,如果你是在本地搭建 Pages 服务,则不需要这一步</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>openssh-server
<span class="nb">sudo </span>service ssh start
</code></pre></div></div>
<p><strong>注意:</strong> 当心 SSH 安全问题!参照此文提高安全性: <a href="/2014/04/27/protect-ssh.html">SSH 安全防护</a></p>
<h3 id="安装web服务器">安装Web服务器</h3>
<p>任何一个 Web 服务器都可以,这里选择 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>nginx
<span class="nb">sudo </span>service nginx start
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/etc/nginx/sites-available/default</code>:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">server</span> <span class="p">{</span>
<span class="n">listen</span> <span class="mi">80</span> <span class="n">default_server</span><span class="p">;</span>
<span class="n">listen</span> <span class="p">[</span><span class="o">::</span><span class="p">]</span><span class="o">:</span><span class="mi">80</span> <span class="n">default_server</span> <span class="n">ipv6only</span><span class="o">=</span><span class="n">on</span><span class="p">;</span>
<span class="n">root</span> <span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="p">;</span>
<span class="n">index</span> <span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">;</span>
<span class="n">charset</span> <span class="n">utf</span><span class="o">-</span><span class="mi">8</span><span class="p">;</span>
<span class="cp"># Make site accessible from http://localhost/
</span> <span class="n">server_name</span> <span class="n">localhost</span><span class="p">;</span>
<span class="n">error_page</span> <span class="mi">404</span> <span class="o">/</span><span class="mf">404.</span><span class="n">html</span><span class="p">;</span>
<span class="n">location</span> <span class="o">/</span> <span class="p">{</span>
<span class="cp"># First attempt to serve request as file, then
</span> <span class="cp"># as directory, then fall back to displaying a 404.
</span> <span class="n">try_files</span> <span class="err">$</span><span class="n">uri</span> <span class="err">$</span><span class="n">uri</span><span class="o">/</span> <span class="o">=</span><span class="mi">404</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp"># Ban xunlei
</span> <span class="k">if</span> <span class="p">(</span><span class="err">$</span><span class="n">http_user_agent</span> <span class="o">~*</span> <span class="err">'</span><span class="n">MSIE</span> <span class="mf">6.0</span><span class="err">'</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">404</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="创建空的-git-仓库">创建空的 Git 仓库</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> ~/blog.git
<span class="nb">cd</span> ~/blog.git
git init <span class="nt">--bare</span>
</code></pre></div></div>
<p>启用<code class="highlighter-rouge">post-upgrade</code>钩子</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mv</span> ~/blog.git/hook/post-update<span class="o">{</span>.sample,<span class="o">}</span>
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">~/blog.git/hook/post-update</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
git update-server-info
git clone ~/blog.git /tmp/blog
jekyll build <span class="nt">-s</span> /tmp/blog <span class="nt">-d</span> /tmp/www
<span class="nb">rm</span> <span class="nt">-rf</span> /tmp/blog
</code></pre></div></div>
<h2 id="在本地向远程仓库推送">在本地向远程仓库推送</h2>
<p>在本地新建一个 Git 仓库用于存储 Pages 的网页</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>blog
<span class="nb">cd </span>blog
git init
<span class="nb">echo</span> <span class="s1">'Hello World!'</span> <span class="o">></span> index.html
git add index.html
git commit <span class="nt">-m</span> <span class="s2">"first commit"</span>
</code></pre></div></div>
<p>将 Debian 上的 Git 仓库添加为此仓库的远程仓库</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git remote add pages ssh://username@server:blog.git
</code></pre></div></div>
<p>向远程推送本地内容</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git push <span class="nt">-u</span> pages
</code></pre></div></div>
<p>每次推送完成后,Git 会自动执行<code class="highlighter-rouge">post-update</code>,调用 Jekyll 更新网页。</p>
浮点数基数排序
https://pxx.io/2014/05/25/float-sort
2014-05-25T00:00:00+08:00
<p>IEEE 754浮点数的机器表示如下:</p>
<table class="table table-bordered table-hover">
<tr>
<td style="width: 40px; text-align: center;">符号</td>
<td style="width: 200px; text-align: center;">指数</td>
<td style="width: 400px; text-align: center;">尾数</td>
</tr>
</table>
<p>比较大小时先比较符号位,再比较指数,最后比较尾数。</p>
<!--more-->
<p><a id="more"></a></p>
<p>反码整数的机器表示如下:</p>
<table class="table table-bordered table-hover">
<tr>
<td style="width: 40px; text-align: center;">符号</td>
<td style="width: 600px; text-align: center;">尾数</td>
</tr>
</table>
<p>比较大小时先比较符号位,再比较尾数。</p>
<p>可以看出,要比较两个浮点数的大小,等价于比较相同机器表示的反码整数的大小。因此,可以把浮点数当成反码整数来进行计数排序或基数排序。需要注意的是,计算机的整数是用补码表示的,还需要一些额外的处理。</p>
<p>代码如下:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "fsort.h"
</span>
<span class="k">typedef</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">uint64</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">int64</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">uint16</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">sort_word</span><span class="p">(</span><span class="kt">double</span> <span class="o">*</span><span class="n">array</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">,</span> <span class="kt">int</span> <span class="n">word</span><span class="p">,</span> <span class="kt">double</span> <span class="o">*</span><span class="n">buf</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">cnt</span><span class="p">[</span><span class="mi">65536</span><span class="p">];</span>
<span class="n">memset</span><span class="p">(</span><span class="n">cnt</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cnt</span><span class="p">));</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">uint16</span> <span class="n">tmp</span> <span class="o">=</span> <span class="p">((</span><span class="n">uint16</span> <span class="o">*</span><span class="p">)(</span><span class="n">array</span><span class="o">+</span><span class="n">i</span><span class="p">))[</span><span class="n">word</span><span class="p">];</span>
<span class="n">cnt</span><span class="p">[</span><span class="n">tmp</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">65536</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">cnt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">cnt</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">array</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="o">*</span><span class="n">n</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">uint16</span> <span class="n">tmp</span> <span class="o">=</span> <span class="p">((</span><span class="n">uint16</span> <span class="o">*</span><span class="p">)(</span><span class="n">buf</span><span class="o">+</span><span class="n">i</span><span class="p">))[</span><span class="n">word</span><span class="p">];</span>
<span class="n">array</span><span class="p">[</span><span class="n">cnt</span><span class="p">[</span><span class="n">tmp</span><span class="p">]</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="n">cnt</span><span class="p">[</span><span class="n">tmp</span><span class="p">]</span><span class="o">--</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">fsort</span><span class="p">(</span><span class="kt">double</span> <span class="o">*</span><span class="n">array</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">double</span> <span class="o">*</span><span class="n">buf</span> <span class="o">=</span> <span class="p">(</span><span class="kt">double</span> <span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="o">*</span><span class="n">n</span><span class="p">);</span>
<span class="n">sort_word</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">);</span>
<span class="n">sort_word</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">buf</span><span class="p">);</span>
<span class="n">sort_word</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">buf</span><span class="p">);</span>
<span class="n">sort_word</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="n">buf</span><span class="p">);</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">array</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="o">*</span><span class="n">n</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(((</span><span class="n">int64</span> <span class="o">*</span><span class="p">)</span><span class="n">buf</span><span class="p">)[</span><span class="n">i</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">array</span><span class="p">[</span><span class="n">n</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">array</span><span class="o">+</span><span class="n">n</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
在 Debian 上安装 Jekyll
https://pxx.io/2014/05/25/debian-jekyll
2014-05-25T00:00:00+08:00
<p><a href="http://jekyllrb.com/">Jekyll</a> 是用 <a href="https://www.ruby-lang.org/">Ruby</a> 编写的静态网站框架,十分流行。本文记录了在 Debian 上安装配置 Jekyll 的过程。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装ruby">安装Ruby</h2>
<p>执行下面的命令:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>ruby
</code></pre></div></div>
<h2 id="安装jekyll">安装Jekyll</h2>
<p>有两种方法安装Jekyll:</p>
<ol>
<li><strong>从软件仓库中安装</strong><br />
比较方便,但安装的Jekyll版本会比较低</li>
<li><strong>使用gem安装</strong><br />
安装稍麻烦,安装的是最新版本</li>
</ol>
<h3 id="从软件仓库中安装">从软件仓库中安装</h3>
<p>执行下面的命令:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>jekyll
</code></pre></div></div>
<h3 id="使用gem安装">使用gem安装</h3>
<p>首先安装<code class="highlighter-rouge">ruby-dev</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>ruby-dev
</code></pre></div></div>
<p>然后使用gem安装:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>gem <span class="nb">install </span>jekyll
</code></pre></div></div>
<p>在运行时发现如下错误:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/var/lib/gems/2.1.0/gems/execjs-2.0.2/lib/execjs/runtimes.rb:51:in <span class="sb">`</span>autodetect<span class="s1">': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
</span></code></pre></div></div>
<p>安装<code class="highlighter-rouge">nodejs</code>后解决:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>nodejs
</code></pre></div></div>
<h2 id="测试">测试</h2>
<p>运行下面的命令测试Jekyll能否正常工作:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll new myblog
<span class="nb">cd </span>myblog
jekyll serve
</code></pre></div></div>
<p>然后在浏览器中打开<a href="http://localhost:4000">http://localhost:4000</a>,应能看到Jekyll默认页面。</p>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://jekyllrb.com/docs/quickstart/">Jekyll quick-start guide</a></li>
</ol>
Debian 7.0 升级到 Debian Testing
https://pxx.io/2014/05/25/debian-dist-upgrade
2014-05-25T00:00:00+08:00
<p>Debian 的 Stable 分支十分稳定,相应的代价就是软件包版本都比较旧。为了能用到比较新的软件包,下面把 Debian 从 Stable 分支(当前是 Debian 7.0)升级到 Testing 分支。(Unstable 分支比 Testing 分支更新,但风险更大)</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="准备条件">准备条件</h2>
<ol>
<li>Internet 连接</li>
<li>足够的磁盘空间</li>
<li>备份数据和配置</li>
</ol>
<h2 id="开始升级">开始升级</h2>
<h3 id="编辑-sourceslist">编辑 sources.list</h3>
<p>备份原来的 <code class="highlighter-rouge">sources.list</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo cp</span> /etc/apt/sources.list /etc/apt/sources.list.backup
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">sources.list</code>,修改下面的内容:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">deb</span> <span class="err">http://mirrors.ustc.edu.cn/debian/</span> <span class="err">testing</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
<span class="err">deb</span> <span class="err">http://mirrors.ustc.edu.cn/debian/</span> <span class="err">testing-proposed-updates</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
<span class="err">deb-src</span> <span class="err">http://mirrors.ustc.edu.cn/debian/</span> <span class="err">testing</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
<span class="err">deb-src</span> <span class="err">http://mirrors.ustc.edu.cn/debian/</span> <span class="err">testing-proposed-updates</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
<span class="err">deb</span> <span class="err">http://mirrors.ustc.edu.cn/debian-security/</span> <span class="err">testing/updates</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
<span class="err">deb-src</span> <span class="err">http://mirrors.ustc.edu.cn/debian-security/</span> <span class="err">testing/updates</span> <span class="err">main</span> <span class="err">non-free</span> <span class="err">contrib</span>
</code></pre></div></div>
<h3 id="升级软件包">升级软件包</h3>
<p>执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get update
<span class="nb">sudo </span>apt-get upgrade
<span class="nb">sudo </span>apt-get dist-upgrade
<span class="nb">sudo </span>apt-get autoremove
</code></pre></div></div>
<p>完成后整个系统就更新到 Testing 分支了,查看系统信息如下:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /etc/os-release
<span class="nv">PRETTY_NAME</span><span class="o">=</span><span class="s2">"Debian GNU/Linux jessie/sid"</span>
<span class="nv">NAME</span><span class="o">=</span><span class="s2">"Debian GNU/Linux"</span>
<span class="nv">ID</span><span class="o">=</span>debian
<span class="nv">ANSI_COLOR</span><span class="o">=</span><span class="s2">"1;31"</span>
<span class="nv">HOME_URL</span><span class="o">=</span><span class="s2">"http://www.debian.org/"</span>
<span class="nv">SUPPORT_URL</span><span class="o">=</span><span class="s2">"http://www.debian.org/support/"</span>
<span class="nv">BUG_REPORT_URL</span><span class="o">=</span><span class="s2">"http://bugs.debian.org/"</span>
</code></pre></div></div>
Arch Linux 搭建 LNMP 环境
https://pxx.io/2014/05/25/arch-lnmp
2014-05-25T00:00:00+08:00
<p>LNMP 是一种通用的 Web 服务器架构,包括:</p>
<ul>
<li><strong>L</strong>inux,操作系统</li>
<li><strong>N</strong>ginx,网页服务器</li>
<li><strong>M</strong>ariaDB或<strong>M</strong>ySQL,数据库管理系统</li>
<li><strong>P</strong>HP,脚本语言</li>
</ul>
<p>这篇文章记录了在 Arch Linux 上搭建 LNMP 环境的过程。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-nginx">安装 Nginx</h2>
<p>从官方仓库中安装 Nginx:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> nginx
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>nginx.service
<span class="nb">sudo </span>systemctl start nginx.service
</code></pre></div></div>
<p><a href="http://tengine.taobao.org/">Tengine</a> 是淘宝在 Nginx 基础上派生的开源项目,与 Nginx 兼容,可以从 AUR 中安装:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> tengine
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>tengine.service
<span class="nb">sudo </span>systemctl start tengine.service
</code></pre></div></div>
<p>在浏览器中打开 <code class="highlighter-rouge">http://127.0.0.1</code>,应该能看到 Nginx 的默认页面。</p>
<h2 id="安装-mariadb">安装 MariaDB</h2>
<p>从官方仓库中安装 MariaDB:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> mariadb
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>mysqld.service
<span class="nb">sudo </span>systemctl start mysqld.service
</code></pre></div></div>
<p>设置 root 用户密码:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mysql_secure_installation
</code></pre></div></div>
<p>完成后重新启动 MariaDB:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl restart mysqld.service
</code></pre></div></div>
<h2 id="安装-php">安装 PHP</h2>
<p>从官方仓库中安装 PHP:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> php
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/php/php.ini</code>,将下面的行取消注释:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">; 设置为存放 PHP 文件的目录
</span><span class="py">open_basedir</span> <span class="p">=</span> <span class="s">/usr/share/nginx/html</span>
<span class="py">extension</span><span class="p">=</span><span class="s">pdo_mysql.so</span>
<span class="py">extension</span><span class="p">=</span><span class="s">mysqli.so</span>
</code></pre></div></div>
<h2 id="在-nginx-中启用-php">在 Nginx 中启用 PHP</h2>
<p>安装<code class="highlighter-rouge">php-fpm</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> php-fpm
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>php-fpm
<span class="nb">sudo </span>systemctl start php-fppm
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/nginx/nginx.conf</code> 或 <code class="highlighter-rouge">/etc/tengine/tengine.conf</code>:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
}
</code></pre></div></div>
<p>重新启动 Nginx、php-fpm</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl restart nginx.service
<span class="nb">sudo </span>systemctl restart php-fpm.service
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="https://wiki.archlinux.org/index.php/LAMP">Arch Linux Wiki: LAMP</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Nginx">Arch Linux Wiki: Nginx</a></li>
<li><a href="https://wiki.archlinux.org/index.php/MySQL">Arch Linux Wiki: MySQL</a></li>
</ol>
《朝闻道》 刘慈欣
https://pxx.io/2014/05/24/朝闻道
2014-05-24T00:00:00+08:00
<p><strong>爱因斯坦赤道</strong></p>
<p> “有一句话我早就想对你们说,”丁仪对妻子和女儿说,“我心中的位置大部分都被物理学占据了,只是努力挤出了一个小角落给你们。对此我心里很痛苦,但也实在是没办法。”</p>
<p> 他的妻子方琳说:“这话你对我说过两百遍了。”</p>
<p> 十岁的女儿文文说:“对我也说过一百遍了。”</p>
<p> 丁仪摇摇头说:“可你们始终没能理解我这话的真正含义,你们不懂得物理学到底是什么。”</p>
<p> 方琳笑着说:“只要它的性别不是女的就行。”</p>
<p> 这里,他们一家三口正坐在一辆时速达五百公里的小车上,行驶在一条直径5米的钢管中,这根钢管的长度约为三万公里,在北纬45度线上绕地球一周。</p>
<!--more-->
<p><a id="more"></a></p>
<p> 小车完全自动行驶,透明的车舱内没有任何驾驶设备。从车里看出去,钢管笔直地伸向前方,小车像是一颗在无限长的枪管中正在射出的子弹,如果不是周围的管壁如湍急的流水飞快掠过,肯定觉察不出车的运动。在小车启动或停车时,可以看到管壁上安装的数量巨大的仪器,还有无数等距离的箍圈,当车加速起来后,它们就在两旁浑然一体地掠过,看不清了。丁仪告诉她们,那些箍圈是用于产生强磁场的超导线圈,而悬在钢管正中的那条细管是粒子通道。</p>
<p> 他们正行驶在人类迄今所建立的最大的粒子加速器中,这台环绕地球一周的加速器被称为爱因斯坦赤道,借助它,物理学家们将实现上世纪那个巨人肩上的巨人最后的梦想:建立宇宙的大统一模型。</p>
<p> 这辆小车本是加速器工程师们用于维修的,现在被丁仪用来带着全家进行环球旅行,这旅行是他早就答应妻子和女儿的,但她们万万没有想到要走这条路。</p>
<p> 整个旅行耗时六十个小时,在这环绕地球一周的行驶中,她们除了笔直的钢管什么都没有看到。不过方琳和文文还是很高兴很满足,至少在这两天多时间里,全家人难得地聚在一起。</p>
<p> 旅行的途中也并不枯燥,丁仪不时指着车外飞速掠过的管壁对文文说:“我们现在正在驶过外蒙古,看到大草原了吗?还有羊群……通过俄罗斯,擦过日本北角。看,朝阳照到积雪的国后岛上了,那可是今天亚洲迎来的第一抹阳光……我们现在在太平洋底了,真黑,什么都看不见。哦不,那边有亮光,暗红色的,嗯,看清了,那是洋底火山口,它涌出的岩浆遇水很快冷却了,所以那暗红光一闪一闪的,像海底平原上的篝火。文文,大陆正在这里生长啊……”</p>
<p> 后来,他们又在钢管中驶过了美国全境,潜过了大西洋,从法国海岸登上了欧洲的土地,驶过意大利和巴尔干半岛,第二次进入俄罗斯,然后从里海回到亚洲,穿过哈萨克斯坦进入中国。现在,他们正走完最后的路程,回到了爱因斯坦赤道在塔克拉玛干沙漠的起点——世界核子中心,这也是环球加速器的控制中心。</p>
<p> 当丁仪一家从控制中心大楼出来时,外面已是深夜,广阔的沙漠静静地在群星下伸向远方,世界显得简单而深邃。</p>
<p> “好了,我们三个基本粒子,已经在爱因斯坦赤道中完成了一次加速试验。”丁仪兴奋地对方琳和文文说。</p>
<p> “爸爸,真的粒子在这根大管子中跑这么一大圈,要多长时间?”文文指着他们身后的加速器管道问,那管道从控制中心两侧向东西两个方向延伸,很快消失在夜色中。</p>
<p> 丁仪回答说:“明天,加速器将首次以它最大的能量运行,在其中运行的每个粒子,将受到相当于一颗核弹的能量的推动,它们将加速到接近光速。这里,每个粒子在管道中只需十分之一秒就能走完我们这两天多的环球旅程。”</p>
<p> 方琳说:“别以为你已经实现了自己的诺言,这次环球旅行是不算的!”</p>
<p> “对!”文文点点头说:“爸爸以后有时间,一定要带我们在这长管子的外面沿着它走一圈,真正看看我们在管子里面到过的地方,那才叫真正的环球旅行呢!”</p>
<p> “不需要,”丁仪对女儿意味深长地说,“如果你睁开了想像力的眼睛,那这次旅行就足够了,你已经在管子中看到了你想看的一切,甚至更多!孩子,更重要的是,蓝色的海洋红色的花朵绿色的森林都不是最美的东西,真正的美眼睛是看不到的,只有想像力才能看到它。与海洋花朵森林不同,它没有色彩和形状,只有当你用想像力和数学把整个宇宙在手中捏成一团儿,使它变成你的一个心爱的玩具,你才能看到这种美……”</p>
<p> 丁仪没有回家,送走妻女后,他回到了控制中心。中心只有不多的几个值班工程师,在加速器建成以后历时两年的紧张调试后,这里第一次这么宁静。</p>
<p> 丁仪上到楼顶,站在高高的露天平台上,他看到下面的加速器管道像一条把世界一分为二的直线,他有一种感觉:夜空中的星星像无数只瞳仁,它们的目光此时都聚焦在下面这条直线上。</p>
<p> 丁仪回到办公室,躺在沙发上睡着了,进入了一个理论物理学家的梦乡。</p>
<p> 他坐在一辆小车里,小车停在爱因斯坦赤道的起点。小车启动,他感觉到了加速时强劲的推力。他在45度纬线上绕地球旋转,一圈又一圈,像轮盘赌上的骰子。随着速度趋近光速,急剧增加的质量使他的身体如一尊金属塑像般凝固了,意识到了这个身体中已蕴含了创世的能量,他有一种帝王般的快感。在最后一圈,他被引入一条支路中,冲进一个奇怪的地方,这是虚无之地。他看到了虚无的颜色,虚无不是黑色也不是白色的,它的色彩就是无色彩,但也不是透明,在这里,空间和时间都还是有待于他去创造的东西。他看到前方有一个小黑点,急剧扩大,那是另一辆小车,车上坐着另一个自己。当他们以光速相撞后同时消失了,只在无际的虚空中留下一个无限小的奇点,这万物的种子爆炸开来,能量火球疯狂暴胀。当弥漫整个宇宙的红光渐渐减弱时,冷却下来的能量天空中物质如雪花般出现了,开始是稀薄的星云,然后是恒星和星系群。在这个新生的宇宙中,丁仪拥有一个量子化的自我,他可以在瞬间从宇宙的一端跃至另一端。其实他并没有跳跃,他同时存在于这两端,他同时存在于这浩大宇宙中的每一点,他的自我像无际的雾气弥漫于整个太空,由恒星沙粒组成的银色沙漠在他的体内燃烧。他无所不在的同时又无所在,他知道自己的存在只是一个概率的幻影,这个多态叠加的幽灵渴望地环视宇宙,寻找那能使自己坍缩为实体的目光。正找着,这目光就出现了,它来自遥远太空中浮现出现的两双眼睛,它们出现在一道由群星织成的银色帷幕后面,那双有着长长睫毛的美丽的眼睛是方琳的,那双充满天真灵性的眼睛是文文的。这两双眼睛在宇宙中茫然扫视,最终没能觉察到这个量子自我的存在,波函数颤抖着,如微风扫过平静的湖面,但坍缩没有发生。正当丁仪陷入绝望之时,茫茫的星海扰动起来,群星汇成的洪流在旋转奔涌。当一切都平静下来时,宇宙间的所有星星构成了一只大眼睛,那只百亿光年大小的眼睛如钻石粉末在黑色的天鹅绒上撒出的图案,它盯着丁仪看,波函数在瞬间坍缩,如倒着放映的焰火影片,他的量子存在凝聚在宇宙中微不足道的一点上,他睁开双眼,回到了现实。</p>
<p> 是控制中心的总工程师把他推醒的,丁仪睁开眼,看到核子中心的几位物理学家和技术负责人围着他躺的沙发站着,他们用看一个怪物的目光盯着他看。</p>
<p> “怎么?我睡过了吗?”丁仪看看窗外,发现天已亮了,但太阳还未升起。</p>
<p> “不,出事了!”总工程师说。这时丁仪才知道,大家那诧异的目光不是冲着他的,而是由于刚出的那件事情。总工程师拉起丁仪,带他向窗口走去。丁仪刚走了两步就被人从背后拉住了,回头一看,是一位叫松田诚一的日本物理学家,上届诺贝尔物理学奖获得者之一。</p>
<p> “丁博士,如果您在精神上无法承受马上要看到的东西,也不必太在意,我们现在可能是在梦中。”日本人说,他脸色苍白,抓着丁仪的手在微微颤抖。</p>
<p> “我刚从梦中出来!”丁仪说,“发生了什么事?”</p>
<p> 大家仍用那种怪异的目光看着他,总工程师拉起他继续朝窗口走去,当丁仪看到窗外的景象时,立刻对自己刚才的话产生了怀疑,眼前的现实突然变得比刚才的梦境更虚幻了。</p>
<p> 在淡蓝色的晨光中,以往他熟悉的横贯沙漠的加速管道消失了,取而代之的是一条绿色的草带,这条绿色大道沿东西两个方向伸向天边。</p>
<p> “再去看看中心控制室吧!”总工程师说。丁仪随着他们来到楼下的控制大厅,又受到一次猝不及防的震撼:大厅中一片空旷,所有的设备都消失得无影无踪,原来放置设备的位置也长满了青草,那草是直接从防静电地板上长出来的。</p>
<p> 丁仪发疯似的冲出控制大厅,奔跑着绕过大楼,站到那条取代加速器管道的草带上,看着它消失在太阳即将升起的东方地平线上,在早晨沙漠寒冷的空气中他打了个寒战。</p>
<p> “加速器的其它部分呢?”他问喘着气跟上来的总工程师。</p>
<p> “都消失了,地上、地下和海中的,全部消失了。”</p>
<p> “也都变成了草?”</p>
<p> “哦不,草只在我们附近的沙漠上有,其它部分只是消失了,地面和海底部分只剩下空空的支座,地下部分只留下空隧道。”</p>
<p> 丁仪弯腰拔起了一束青草,这草在别的地方看上去一定很普通,但在这里就很不寻常:它完全没有红柳或仙人掌之类的耐旱的沙漠植物的特点,看上去饱含水分,青翠欲滴,这样的植物只能生长在多雨的南方。丁仪搓碎了一根草叶,手指上沾满了绿色的汁液,一股淡淡的清香飘散开来。丁仪盯着手上的小草呆立了很长时间,最后说:“看来,这真是梦了。”</p>
<p> 东方传来一个声音:“不,这是现实!”</p>
<p><strong>真空衰变</strong></p>
<p> 在绿色草路的尽头,朝阳已升起了一半,它的光芒照花了人们的眼睛。在这光芒中,有一个人沿着草路向他们走来,开始他只是一个以日轮为背景的剪影,剪影的边缘被日轮侵蚀,显得变幻不定。当那人定近些后,人们看到他是一名中年男子,穿着白衬衣和黑裤子,没打领带。再近些,他的面孔也可以看清了,这是一张兼具亚洲和欧洲人特点的脸,这一点在这个地区并没有什么不寻常。但人们绝不会把他误认为是当地人,他的五宫太端正了,端正得有些不现实,像某些公共标志上表示人类的一个图符。当他再走近些时,人们也不会把他误认为是这个世界的入了,他并没有走,他一直两腿并拢笔直地站着,鞋底紧贴着草地飘浮而来。在距他们两三米处,来人停了下来。</p>
<p> “你们好,我以这个外形出现是为了我们之间能更好地交流,不管各位是否认可我的人类形象,我已经尽力了。”来人用英语说,他的话音一如其面孔,极其标准而无特点。</p>
<p> “你是谁?”有人问。</p>
<p> “我是这个宇宙的排险者。”</p>
<p> 这个回答中有两个含义深刻的字立刻深入了物理学家们的脑海:“这个宇宙!”</p>
<p> “您和加速器的消失有关吗?”总工程师问。</p>
<p> “它在昨天夜里被蒸发了,你们计划中的试验必须被制止。作为补偿,我送给你们这些草,它们能在干旱的沙漠上以很快的速度成长蔓延。”</p>
<p> “可这些都是为了什么呢?”</p>
<p> “这个加速器如果真以最大功率运行,能将粒子加速到10的20次方电子伏特,这接近宇宙大爆炸的能量,可能给我们的宇宙带来灾难。”</p>
<p> “什么灾难?”</p>
<p> “宇宙衰变。”</p>
<p> 听到这回答,总工程师扭头看了看身边的物理学家们,他们都沉默不语,紧锁眉头思考着什么。</p>
<p> “还需要进一步解释吗?”排险者问。</p>
<p> “不,不需要了。”丁仪轻轻地摇摇头说。物理学家们本以为排险者会说出一个人类完全无法理解的概念,但没想到。他说出的东西人类的物理学界早在上世纪八十年代初就想到了,只是当时大多数人都认为那不过是一个新奇的假设,与现实毫无关系,以至现在几乎被遗忘了。</p>
<p> 真空衰变的概念最初出现在1980年《物理评论》杂志上的一篇论文中,作者是西德尼?科尔曼和弗兰克?德卢西亚。早在这之前狄拉克就指出,我们宇宙中的真空可能是一种伪真空,在那似乎空无一物的空间里,幽灵般的虚粒子在短得无法想像的瞬间出现又消失,这瞬息间创生与毁灭的活剧在空间的每一点上无休止地上演,使得我们所说的真空实际上是一个沸腾的量子海洋,这就使得真空具有一定的能级。科尔曼和德卢西亚的新思想在于:他们认为某种高能过程可能产生出另一种状态的真空,这种真空的能级比现有的真空低,甚至可能出现能级为零的“真真空”。这种真空的体积开始可能只有一个原子大小,但它一旦形成,周围相邻的高能级真空就会向它的能级跌落,变成与它一样的低能级真空,这就使得低能级真空的体积迅速扩大,形成一个球形,这个低能级真空球的扩张很快就能达到光速,球中质子和中子将在瞬间衰变,这使得球内的物质世界全部蒸发,一切归于毁灭……“……以光速膨胀的低能级真空球将在0.03秒内毁灭地球,五个小时内毁灭太阳系,四年后毁灭最近的恒星,十万年后毁灭银河系……没有什么能阻止球体的膨胀,随时时间的推移,整个宇宙都难逃劫难。”排险者说,他的话正好接上了大多数人的思维,难道他能看到人类的思想?排险者张开双臂,做出一个囊括一切的姿势,“如果把我们的宇宙看作一个广阔的海洋,我们就是海中的鱼儿,我们周围这无边无际的海水是那么清澈透明,以至于我们忘记了它的存在。现在我要告诉你们,这不是海水,是液体炸药,一粒火星就会引发毁灭一切的大灾难。作为宇宙排险者,我的职责就是在这些火星期到危险的温度前扑灭它。”</p>
<p> 丁仪说:“这大概不大容易,我们已知的宇宙有二百亿光年半径,即使对于你们这样的超级文明,这也是一个极其广阔的空间。”</p>
<p> 排险者笑了笑,这是他第一次笑,这笑同样毫无特点:“没有你想的那么复杂。你们已经知道,我们目前的宇宙,只是大爆炸焰火的余烬,恒星和星系,不过是仍然保持着些许温热的飘散的烟灰罢了,这是一个低能级的宇宙,你们看到的类星体之类的高能天体只存在于遥远的过去。在目前的自然宇宙中,最高级别的能量过程,如大质量物体坠入黑洞,其能级也比大爆炸低许多数量级。在目前的宇宙中,发生创世级别的能量过程的惟一机会,只能来自于其中的智慧文明探索宇宙终极奥秘的努力,这种努力会把大量的能量聚焦到一个微观点上,使这一点达到创世能级。所以,我们只需要监视宇宙中进化到一定程度的文明世界就行了。”</p>
<p> 松田诚一问:“那么,你们是从何时起开始注意到人类呢?普郎克时代吗?”</p>
<p> 排险者摇摇头。</p>
<p> “那么是牛顿时代?也不是?不可能远到亚里士多德时代吧?”</p>
<p> “都不是。”排险者说,“宇宙排险系统的运行机制是这样的:它首先通过散布在宇宙中的大量传感器监视已有生命出现的世界,当发现这些世界中出现有能力产生创世能级能量过程的文明时,传感器就发出警报,我这样的排险者在收到警报后将亲临那些世界监视其中的文明。但除非这些文明真要进行创世能级的试验,我们是绝不会对其进行任何干预的。”</p>
<p> 这时,在排险者的头部左上方出现了一个黑色的正方形,约两米见方,正方形充满了深不见底的漆黑,仿佛现实被控了一个洞。几秒钟后,那黑色的空间中出现了一个蓝色的地球影像,排险者指着影像说:“这就是放置在你们世界上方的传感器拍下的地球影像。”</p>
<p> “这个传感器是在什么时候放置于地球的?”有人问。</p>
<p> “按你们的地质学纪年,在古生代末期的石炭纪。”</p>
<p> “石炭纪?”“那就是……三亿年前了!”人们纷纷惊呼。</p>
<p> “这……太早了些吧?”总工程师敬畏地问。</p>
<p> “早吗?不。是太晚了,当我们第一次到达石炭纪的地球,看到在广阔的冈瓦纳古陆上,皮肤湿滑的两栖动物在原生松林和沼泽中爬行时,真吓出了一身冷落。在这之前的相当长的岁月里,这个世界都有可能突然进化出技术文明,所以,传感器应该在古生代开始时的寒武纪或奥陶纪就放置在这里。”</p>
<p> 地球的影像向前推来,充满了整个正方形,镜头在各大陆间移动,让人想到一双警惕巡视的眼睛。</p>
<p> 排险者说:“你们现在看到的影像是在更新世末期拍摄的,距今37万年,对我们来说,几乎是在昨天了。”</p>
<p> 地球表面的影像停止了移动,那双眼睛的视野固定在非洲大陆上,这个大陆正处于地球黑夜的一侧,看上去是一个由稍亮些的大洋三面围绕的大墨块。显然大陆上的什么东西吸引了这双眼睛的注意,焦距拉长,非洲大陆向前扑来,很快占据了整个画面,仿佛观察者正在飞速冲向地球表面。陆地黑白相间的色彩渐渐在黑暗中显示出来,白色的是第四纪冰期的积雪,黑色部分很模糊,是森林还是布满乱石的平原,只能由人想像了。镜头继续拉近,一个雪原充满了画面,显示图像的正方形现在全变成白色了,是那种夜间雷地的灰白色,带着暗暗的谈蓝。在这雪原上有几个醒目的黑点,很快可以看出那是几个人影,接着可以看出他们的身型都有些驼背,寒冷的夜风吹起他们长长的披肩乱发。图像再次变黑,一个人仰起的面孔充满了面画,在微弱的光线里无法看清这张面孔的细部,只能看出他的眉骨和颧骨很高,嘴唇长而薄。镜头继续拉近,这似乎已是不可能再近的距离,一双深陷的眼睛充满了画面,黑暗中的瞳仁中有一些银色的光斑,那是映在其中的变形的星空。</p>
<p> 图像定格,一声尖利的呜叫响起,排险者告诉人们,预警系统报警了。</p>
<p> “为什么?”总工程师不解地问。</p>
<p> “这个原始人仰望星空的时间超过了预誓阀值,已对宇宙表现出了充分的好奇。到此为止,已在不同的地点观察到了十例这样的超限事件,符合报警条件。”</p>
<p> “如果我没记错的话,你前面说过,只有当有能力产生创世能级能量、过程的文明出现时,预警系统才会报警。”</p>
<p> “你们看到的不正是这样一个文明吗?”</p>
<p> 人们面面相觑,一片茫然。</p>
<p> 排险者露出那毫无特点的微笑说:“这很难理解吗?当生命意识到宇宙奥秘的存在时,距它最终解开这个奥秘只有一步之遥了。”看到人们仍不明白,他接着说,“比如地球生命,用了四十多亿年时间才第一次意识到宇宙奥秘的存在,但那一时刻距你们建成爱因斯坦赤道只有不到四十万年时间,而这一进程最关键的加速期只有不到五百年时间。如果说那个原始人对字宙的几分钟凝视是看到了一颗宝石,其后你们所谓的整个人类文明,不过是弯腰去拾它罢了。”</p>
<p> 丁仪若有所悟地点点头:“要说也是这样,那个伟大的望星人!”</p>
<p> 排险者接着说:“以后我就来到了你们的世界,监视着文明的进程,像是守护着一个玩火的孩子。周围被火光照壳的宇宙使这孩子着迷,他不顾一切地把火越燃越旺,直到现在,宇宙已有被这火烧毁的危险。”</p>
<p> 丁仪想了想,终于提出了人类科学史上最关键的问题:“这就是说,我们永远不可能得到大统一模型,永远不可能探知宇宙的终极奥秘?”</p>
<p> 科学家们呆呆地盯着排险者,像一群在最后审判日里等待宣判的灵魂。</p>
<p> “智慧生命有多种悲哀,这只是其中之一。”排险者谈谈地说。</p>
<p> 松田诚一声音频抖地问:“作为更高一级的文明,你们是如何承受这种悲哀的呢?”</p>
<p> “我们是这个宇宙中的幸运儿,我们得到了宇宙的大统一模型。”科学家们心中的希望之火又重新开始燃烧。</p>
<p> 丁仪突然想到了另一种恐怖的可能:“难道说,真空衰变已被你们在宇宙的某处触发了?”</p>
<p> 排险者摇摇头:“我们是用另一种方式得到的大统一模型,这一时说不清楚,以后我可能会详细地讲给你们听。”</p>
<p> “我们不能重复这种方式吗?”排险者继续摇头:“时机已过,这个宇宙中的任何文明都不可能再重复它。”</p>
<p> “那请把宇宙的大统一模型告诉人类!”</p>
<p> 排险者还是摇头。</p>
<p> “求求你,这对我们很重要,不,这就是我们的一切!”丁仪冲动地去抓排险者的胳膊,但他的手毫无感觉地穿过了排险者的身体。</p>
<p> “知识密封准则不允许这样做。”</p>
<p> “知识密封准则?”</p>
<p> “这是宇宙中文明世界的最高准则之一,不允许高级文明向低级文明传递知识,我们把这种行为叫知识的管道传递。低级文明只能通过自己的探索来得到知识。”</p>
<p> 丁仪大声说:“这是一个不可理解的准则:如果你们把大统一模型告诉所有渴求宇宙最终奥秘的文明,他们就不会试图通过创世能级的高能试验来得到它,宇宙不就安全了吗?”</p>
<p> “你想得太简单了:这个大统一模型只是这个宇宙的。当你们得到它后就会知道,还存在着无数其它的宇宙,你们接着又会渴求得到制约所有宇宙的超统一模型。而大统一模型在技术上的应用会使你们拥有产生更高能量过程的手段,你们会试图用这种能量过程击穿不同宇宙间的壁垒,不同宇宙间的真空存在着能级差,这就会导致真空衰变,同时毁灭两个或更多的宇宙。知识的管道传递还会对接收它的低级文明产生其它更直接的不良后果和灾难,其原因大部分你们目前还无法理解,所以知识密封准则是绝对不允许违反的。这个准则所说的知识不仅是宇宙的深层秘密,它是指所有你们不具备的知识,包括各个层次的知识:假设人类现在还不知道牛顿三定律或微积分,我也同样不能传授给你们。”</p>
<p> 科学家们沉默了,在他们眼中,已升得很高的太阳熄灭了,一切都陷入黑暗之中。整个宇宙顿时变成一个巨大的悲剧,这悲剧之大之广他们一时还无法把握,只能在余生细水长流地受其折磨,事实上他们知道,余生已无意义。</p>
<p> 松田诚一瘫坐在草地上,说了一句后来成为名言的话:“在一个不可知的宇宙里,我的心脏懒得跳动了”。他的话道出了所有物理学家的心声,他们目光呆滞,欲哭无泪。就这样不知过了多长时间,丁仪突然打破沉默:“我有一个办法,既可以使我得到大统一模型,又不违反知识密封准则。”排险者对他点点头:“说说看。”</p>
<p> “你把宇宙的终极奥秘告诉我,然后毁灭我。”</p>
<p> “给你三天时间考虑。”排险者说,他的回答不假思索十分迅速,紧接着丁仪的话。</p>
<p> 丁仪欣喜若狂:“你是说这可行?”</p>
<p> 排险者点点头。</p>
<p><strong>真理祭坛</strong></p>
<p> 人们是这么称呼那个巨大的半球体的,它的直径五十米,底面朝上球面向下放置在沙漠中,远看像一座倒放的山丘。这个半球是排险者用沙子筑成的,当时沙漠中出现了一股巨大的龙卷风,风中那高大的沙柱最后凝聚成这个东西。谁也不知道他是用什么东西使大量的沙子聚合成这样一个精确的半球形状,其强度使它球面朝下放置都不会解体。但半球这样的放置方式使它很不稳定,在沙漠中的阵风里它有明显的摇晃。</p>
<p> 据排险者说,在他的那个遥远世界里,这样的半球是一个论坛,在那个文明的上古时代,学者们就聚集在上面讨论宇宙的奥秘。由于这样放置的半球的不稳定性,论坛上的学者们必须小心地使他们的位置均匀地分布,否则半球就会倾斜,使上面的人都滑下来。排险者一直没有解释这个半球形论坛的含义,人们猜测,它可能是暗示宇宙的非平衡态和不稳定。</p>
<p> 在半球的一侧,还有一条沙子构筑的长长的坡道,通过它可以从下面走上祭坛。在排险者的世界里,这条坡道是不需要的:在纯能化之前的上古时代,他的种族是一种长着透明双翼的生物,可以直接飞到论坛上。这条坡道是专为人类修筑的,他们中的三面多人将通过它走上真理祭坛,用生命换取宇宙奥秘。</p>
<p> 三天前,当排险者答应了丁仪的要求后,事情的发展令世界恐慌:在短短一天时间内,有几百人提出了同样的要求,这些人除了世界核子中心的其他科学家外,还有来自世界各国的学者,开始只有物理学家,后来报名者的专业越出了物理学和宇宙学,出现了数学、生物学等其它基础学科的科学家,甚至还有经济学和史学这类非自然科学的学者。这些要求用生命来换取真理的人,都是他们所在学科的刀锋,是科学界精英中的精英,其中诺贝尔奖获得者就占了一半,可以说,在真理祭坛前聚集了人类科学的精华。</p>
<p> 真理祭坛前其实已不是沙漠了,排险者在三天前种下的草迅速蔓延,那条草带已宽了两倍,它那已变得不规则的边曲已伸到了真理祭坛下面。在这绿色的草地上凝集了上万人,除了这些即将献身的科学家和世界各大媒体的记者外,还有科学家们的亲人和朋友,两天两夜无休止的劝阻和哀求已使他们心力交瘁,精神都处于崩溃的边缘,但他们还是决定在这最后的时刻做最后的努力。与他们一同做这种努力的还有数量众多的各国政府的代表,其中包括十多位国家元首,他们也竭力留住自己国家的科学精英。</p>
<p> “你怎么把孩子带来了?”丁仪盯着方琳问,在他们身后,毫不知情的文文正在草地上玩耍,她是这群表情阴沉的人中惟一的快乐者。</p>
<p> “我要让她看着你死。”方琳冷冷地说,她脸色苍白,双眼无目标地平视远方。</p>
<p> “你认为这能阻止我?”</p>
<p> “我不抱希望,但能阻止你女儿将来像你一样。”</p>
<p> “你可以惩罚我,但孩子……”</p>
<p> “没人能惩罚你,你也别把即将发生的事伪装成一种惩罚,你正走在通向自己梦中天堂的路上!”</p>
<p> 丁仪直视着爱人的双眼说:“琳,如果这是你的真实想法,那么你终于从最深处认识了我。”</p>
<p> “我谁也不认识,现在我的心中只有仇恨。”</p>
<p> “你当然有权恨我。”</p>
<p> “我恨物理学!”</p>
<p> “可如果没有它,人类现在还是丛林和岩洞中愚钝的动物。”</p>
<p> “但我现在并不比它们快乐多少!”</p>
<p> “但我快乐,也希望你能分享我的快乐。”</p>
<p> “那就让孩子也一起分享吧,当她亲眼看到父亲的下场,长大后至少会远离物理学这种毒品!”</p>
<p> “琳,把物理学称为毒品。你也就从最深处认识了它。看,在这两天你真正认识了多少东西,如果你早些理解这些,我们就不会有现在的悲剧了。”</p>
<p> 那几位国家元首则在真理祭坛上努力劝说排险者,让他拒绝那些科学家的要求。</p>
<p> 美国总统说:“先生——我可以这么称呼您吗?我们的世界里最出色的科学家都在这里了,您真想毁灭地球的科学吗?”</p>
<p> 排险者说:“没有那么严重,另一批科学精英会很快涌现并补上他们的位置,对宇宙奥秘的探索欲望是所有智慧生命的本性。”</p>
<p> ”既然同为智慧生命,您就忍心杀死这些学者吗?</p>
<p> “这是他们自己的选择,生命是他们自己的,他们当然可以用它来换取自己认为崇高的东西。”</p>
<p> “这个用不着您来提醒我们!”俄罗斯总统激动地说,“用生命来换取崇高的东西对人类来说并不陌生,在上个世纪的一场战争中,我的国家就有两千多万人这么做了。但现在的事实是,那些科学家的生命什么都换不到!只有他们自己能得知那些知识,这之后,你只给他们十分钟的生存时间!他们对终极真理的欲望已成为一种地地道道的变态,这您是清楚的!”</p>
<p> “我清楚的是,他们是这个星球上仅有的正常人。”</p>
<p> 元首们面面相觑,然后都困惑地看着排险者。说他们不明白他的意思。</p>
<p> 排险者伸开双管拥抱天空:“当宇宙的和谐之美一览无遗地展现在你面前时。生命只是一个很小的代价。”</p>
<p> “但他们看到这美后只能再活十分钟!”</p>
<p> “就是没有这十分钟,仅仅经历看到那终极之美的过程,也是值得的。”</p>
<p> 元首们又互相看了看,都摇头苦笑。</p>
<p> “随着文明的进化,像他们这样的人会渐渐多起来的,”排险者指指真理祭坛下的科学家们说,“最后,当生存问题完全解决,当爱情因个体的异化和融和而消失,当艺术因过分的精致和晦涩而最终死亡,对宇宙终极美的追求便成为文明存在的惟一寄托,他们的这种行为方式也就符合了整个世界的基本价值观。”</p>
<p> 元首们沉默了一会儿,试着理解排险者的话,美国总统突然哈哈大笑起来:“先生,您在耍我们,您在耍弄整个人类!”</p>
<p> 排险者露出一脸困惑:“我不明白……”</p>
<p> 日本首相说:“人类还没有笨到你想像的程度,你话中的逻辑错误连小孩子都明白!”</p>
<p> 排险者显得更加困惑了:“我看不出这有什么逻辑错误。”</p>
<p> 美国总统冷笑着说:“一万亿年后,我们的宇宙肯定充满了高度进化的文明。照您的意思,对终极真理的这种变态的欲望将成为整个宇宙的基本价值观,那时全宇宙的文明将一致同意,用超高能的试验来探索囊括所有宇宙的超统一模型,不惜在这种试验中毁灭包括自己在内的一切?您想告诉我们这种事会发生?”</p>
<p> 排险者盯着元首们长时间不说话,那怪异的目光使他们不寒而栗,他们中有人似乎悟出了什么:“您是说……”</p>
<p> 排险者举起一只手制止他说下去,然后向真理祭坛的边缘走去,在那里,他用响亮的声音对所有人说:“你们一定很想知道我们是如何得到这个宇宙的大统一模型的,现在可以告诉你们了。”很久很久以前,我们的宇宙比现在小得多,而且很热,恒星还没有出现。但已有物质从能量中沉淀出来,形成弥漫在发着红光的太空中的星云。这时生命已经出现了,那是一种力场与稀薄的物质共同构成的生物,其个体看上去很像太空中的龙卷风。这种星云生物的进化速度快得像闪电,很快产生了遍布全宇宙的高度文明。当星云文明对宇宙终极真理的渴望达到顶峰时,全宇宙的所有世界一致同意,冒着真空衰变的危险进行创世能级的试验,以探索宇宙的大统一模型。”</p>
<p> “星云生物操纵物质世界的方式与现今宇宙中的生命完全不同,由于没有足够多的物质可供使用,他们的个体自己进化为自己想要的东西。在最后的决定做出后,某些世界中的一些个体飞快地进化,把自己进化为加速器的一分部。最后,上百万个这样的星云生物排列起来,组成了一台能把粒子加速到创世能级的高能加速器。加速器启动后,暗红色的星云中出现了一个发出耀眼蓝光的灿烂光环。”</p>
<p> “他们深知这个试验的危险,在试验进行的同时把得到的结果用引力波发射出去,引力波是惟一能在真空衰变后存留下来的信息载体。”</p>
<p> “加速器运行了一段时间后,真空衰变发生了,低能级的真空球从原子大小以光速膨胀,转眼间扩大到天文尺度,内部的一切蒸发殆尽。真空球的膨胀速度大于宇宙的膨胀速度,虽然经过了浸长的时间,最后还是毁灭了整个宇宙。”</p>
<p> “漫长的岁月过去了,在空无一物的宇宙中,被蒸发的物质缓慢地重新沉淀凝结,星云又出现了,但宇宙一片死寂,直到恒星和行星出现,生命才在宇宙中重新萌发。而这时,早已毁灭的星云文明发出的引力波还在宇宙中回荡,实体物质的重新出现使它迅速衰减,但就在它完全消失以前,被新宇宙中最早出现的文明接收到,它所带的信息被破译,从这远古的试验数据中,新文明得到了大统一模型。他们发现,对建立模型最关键的数据,是在真空衰变前万分之一秒左右产生的。”</p>
<p> “让我们的思绪再回到那个毁灭中的星云宇宙,由于真空球以光速膨胀,球体之外的所有文明世界都处于光锥视界之外,不可能预知灾难的到来。在真空球到达之前,这些世界一定在专心地接收着加速器产生的数据。在他们收到足够建立大统一模型的数据后的万分之秒,真空球毁灭了一切。但请注意一点:星云生物的思维频率极高,万分之一秒对他们来说是一段相当长的时间,所以他们有可能在生命的最后时刻推导出了大统一模型。当然,这也可能只是我们的一种自我安慰,更有可能的是他们最后什么也没推导出来。星云文明掀开了宇宙的面纱,但他们自己没来得及向宇宙那终极的美瞥一眼就毁灭了。更为可敬的是,开始试验前他们可能已经想到了这种可能,牺牲自己,把那些包含着宇宙终极秘密的数据传给遥远未来的文明。”</p>
<p> “现在你们应该明白,对宇宙终极真理的追求,是文明的最终目标和归宿。”</p>
<p> 排险者的讲述使真理祭坛上下的所有人陷入长久的沉思中,不管这个世界对他最后那句话是否认同,有一点可以肯定:它将对今后人类思想和文化的进程产生重大影响。</p>
<p> 美国总统首先打破沉默说:“您为文明描述了一幅阴暗的前景,难道生命这漫长进程中所有的努力和希望,都是为了那飞娥扑火的一瞬间?”</p>
<p> “飞蛾并不觉得阴暗,它至少享受了短暂的光明。”</p>
<p> “人类绝不可能接受这样的人生观!”</p>
<p> “这完全可以理解。在我们这个真空衰变后重生的宇宙中,文明还处于萌芽阶段,各个世界都有自己的生活方式,追求着不同的目标。对大多数世界来说,对终极真理的追求并不具有至高无上的意义,为此而冒着毁灭宇宙的危险,对宇宙中大多数生命是不公平的,即使在我自己的世界中。也并非所有的成员都愿意为此牺牲一切。所以,我们自己没有继续进行探索超统一模型的高能试验,并在整个宇宙中建立了排险系统。但我们相信,随着文明的进化,总有一天宇宙中的所有世界都会认同文明的终极目标。其实就是现在,就是在你们这样一个婴儿文明中,已经有人认同了这个目标。好了,时间快到了,如果各位不想用生命换取真理,就请你们下去,让那些想这么做的人上来。”</p>
<p> 元首们走下真理祭坛,来到那些科学家面前,进行最后的努力。</p>
<p> 法国总统说:“能不能这样:把这事稍往后放一放,让我陪大家去体验另一种生活,让我们放松自己,在黄昏的鸟鸣中看着夜幕降临大地,在银色的月光下听着怀旧的音乐,喝着美酒想着你心爱的人……这时你们就会发现,终级真理并不像你们想的那么重要,与你们追求的虚无飘渺的宇宙和谐之美相比,这样的美更让人陶醉。”</p>
<p> 一位物理学家冷冷地说:“所有的生活都是合理的,我们没必要互相理解。”</p>
<p> 法国元首还想说什么,美国总统已失去了耐心:“好了,不要对牛弹琴了!您还看不出来这是怎样一群毫无责任心的人?还看不出这是怎样一群骗子?他们声称为全人类的利益而研究,其实只是拿社会的财富满足自己的欲望,满足他们对那种玄虚的宇宙和谐美的变态欲望,这和拿公款嫖娼有什么区别!”</p>
<p> 丁仪挤上前来拍拍他的肩膀笑着说:“总统先生,科学发展到今天,终于有人对它的本质进行了比较准确的定义。”</p>
<p> 旁边的松田诚一说:“我们早就承认这点,并反复声明,但一直没人相信我们。”</p>
<p><strong>交换</strong></p>
<p> 生命和真理的交换开始了。</p>
<p> 第一批八位数学家沿着长长的坡道向真理祭坛走去。这时,沙漠上没有一丝风,仿佛大自然屏住了呼吸,寂静笼罩着一切,刚刚升起的太阳把他们的影子长长地投在沙漠上,那几条长影是这个凝固的世界中唯一能动的东西。</p>
<p> 数学家们的身影消失在真理祭坛上。下面的人们看不到他们了。所有的人都凝神听着,他们首失听到祭坛上传来的排险者的声音,在死一般的寂静中这声音很清晰:“请提出问题。”</p>
<p> 接着是一位数学家的声音:“我们想看到费尔玛和哥德巴赫两个猜想的最后证明。”</p>
<p> “好的,但证明很长,时间只够你们看关键的部分,其余用文字说明。”排险者是如何向科学家们传授知识的,以后对人类一直是个谜。在远处的监视飞机上拍下的图像中,科学家们都在仰起头看着天空,而他们看的方向上空无一物。一个普遍被接受的说法是:外星人用某种思维波把信息直接输入到他们的大脑中。但实际情况比那要简单得多:排险者把信息投射在天空上,在真理祭坛上的人看来,整个地球的天空变成了一个显示屏,而在祭坛之外的角度什么都看不到。</p>
<p> 一个小时过去了,真理祭坛上有个声音打破了寂静,有人说:“我们看完了。”</p>
<p> 接着是排险者平静的回答:“你们还有十分钟的时间。”</p>
<p> 真理祭坛上隐隐传来了多个人的交谈声,只能听清只言片语,但能清楚地感受到那些人的兴奋和喜悦,像是一群在黑暗的隧道中跋涉了一年的人突然看到了洞口的光亮。</p>
<p> “……这完全是全新的……”</p>
<p> “……怎么可能……”“……我以前在直觉上……”“……天啊,真是……”</p>
<p> 当十分钟就要结束时,真理祭坛上响起了一个清晰的声音:“请接受我们八个人真诚的谢意。”</p>
<p> 真理祭坛上闪起一片强光,强光消失后,下面的人们看到八个等离子体火球从祭坛上升起,轻盈地向高处飘升。它们的光度渐渐减弱,由明亮的黄色变成柔和的橘红色,最后一个接一个地消失在蓝色的天空中,整个过程悄无声息。从监视飞机上看,真理祭坛上只剩下排险者站在圆心。</p>
<p> “下一批!”他高声说。</p>
<p> 在上万人的凝视下,又有十一个人走上了真理祭坛。</p>
<p> “请提出问题。”</p>
<p> “我们是古生物学家,想知道地球上恐龙灭绝的真正原因。”</p>
<p> 古生物学家们开始仰望长空,但所用的时间比刚才数学家们短得多,很快有人对排险者说:“我们知道了,谢谢!”</p>
<p> “你们还有十分钟。”</p>
<p> “……好了,七巧板对上了……”“……做梦也不会想到那方面去……”“……难道还有比这更……”</p>
<p> 然后强光出现又消失,十一个火球从真理祭坛上飘起,很快消失在沙漠上空。……一批又一批的科学家走上真理祭坛,完成了生命和真理的交换,在强光中化为美丽的火球飘逝而去。</p>
<p> 一切都在庄严与宁静中进行,真理祭坛下面,预料中生离死别的景象并没有出现,全世界的人们静静地看着这壮丽的景象,心灵被深深地震慑了。人类在经历着一场有史以来最大的灵魂洗礼。</p>
<p> 一个白天的时间不知不觉过去了,太阳已在西方地平线处落下了一半,夕阳给真理祭坛撤上了一层金辉。物理学家们开始走向祭坛,他们是人数最多的一批,有八十六人。就在这一群人刚刚走上坡道时,从日出时一直持续到现在的寂静被一个童声打破了。</p>
<p> “爸爸!”文文哭喊着从草坪上的人群中冲出来,一直跑到坡道前,冲进那群物理学家中,抱住了丁仪的腿,“爸爸,我不让你变成火球飞走!”</p>
<p> 丁仪轻轻抱起了女儿,问她:“文文,告诉爸爸,你能记起来的最让自己难受的事是什么?”</p>
<p> 文文抽泣着想了几秒钟,说:“我一直在沙漠里长大,最……最想去动物园。上次爸爸去南方开会,带我去了那边的一个大大的动物园,可刚进去,你的电话就响了,说工作上有急事。那是个天然动物园,小孩儿一定要大人带着才能进去,我也只好跟你回去了,后来你再也没时间带我去。爸爸,这是最让我难受的事儿,在回来的飞机上我一直哭。”</p>
<p> 丁仪说:“但是,好孩子,那个动物园你以后肯定有机会去,妈妈以后会带文文去的。爸现在也在一个大动物园的门口,那里面也有爸爸做梦都想看到的神奇的东西,而爸爸如果这次不去,以后真的再也没机会了。”</p>
<p> 文文用泪汪汪的大眼睛呆呆地看了爸爸一会儿,点点头说:“那……那爸爸就去吧。”</p>
<p> 方琳走过来,从丁仪怀中抱走了女儿,眼睛看着前面矗立的真理祭坛说:“文文,你爸爸是世界上最坏的爸爸,但他真的很想去那个动物园。”</p>
<p> 丁仪两眼看着地面,用近乎祈求的声调说:“是的文文,爸爸真的很想去。”</p>
<p> 方琳用冷冷的目光看着丁仪说:“冷血的基本粒子,去完成你最后的碰撞吧。记住,我绝不会让你女儿成为物理学家的!”</p>
<p> 这群人正要转身走去,另一个女性的声音使他们又停了下来。“松田君,你要再向上走,我就死在你面前!”</p>
<p> 说话的是一位娇小美丽的日本姑娘,她此时站在坡道起点的草地上,把一支银色的小手枪顶在自己的太阳穴上。</p>
<p> 松田诚一从那群物理学家中走了出来,走到姑娘的面前,直视着她的双眼说:“泉子,还记得北海道那个寒冷的早晨吗?你说要出道题考验我是否真的爱你,你问我,如果你的脸在火灾中被烧得不成样子,我该怎么办?我说我将忠贞不渝地陪伴你一生。你听到这回答后很失望,说我并不是真的爱你,如果我真的爱你,就会弄瞎自己的双眼,让一个美丽的泉子永远留在心中。”</p>
<p> 泉子拿枪的手没有动,但美丽的双眼盈满了泪水。</p>
<p> 松田诚一接着说:“所以,亲爱的,你深知美对一个人生命的重要。现在,宇宙终极之美就在我面前,我能不看她一眼吗?”</p>
<p> “你再向上走一步我就开枪!”</p>
<p> 松田诚一对她微笑了一下,轻声说:“泉子,天上见。”然后转身和其他物理学家一起沿坡道走向真理祭坛。身后脆弱的枪声和柔软的躯体倒地的声音,都没使他们回头。</p>
<p> 物理学家们走上了真理祭坛那圆形的顶面,在圆心。排险者微笑着向他们致意。突然间,映着晚霞的天空消失了,地平线处的夕阳消失了,沙漠和草地都消失了。真理祭坛悬浮于无际的黑色太空中,这是创世前的黑夜,没有一颗星星。排险音挥手指向一个方向,物理学家们看到在遥远的黑色深渊中有一颗金色的星星,它开始小得难以看清,后来由一个亮点渐渐增大,开始具有面积和形状,他们看出那是一个向这里飘来的旋涡星系。星系很快增大,显出它磅澜的气势。距离更近一些后,他们发现星系中的恒星都是数字和符号,它们组成的方程式构成了这金色星海中的一排排波浪。</p>
<p> 宇宙大统一模型缓慢而庄严地从物理学家们的上空移过。……当八十六个火球从真理祭坛上升起时,方琳跟前一黑倒在草地上,她隐约听到文文的声音:“妈妈,那些哪个是爸爸?”</p>
<p> 最后一个上真理祭坛的人是史蒂芬·霍金,他的电动轮椅沿着长长的坡道慢慢向上移动,像一只在树枝上爬行的昆虫。他那仿佛已抽去骨骼的绵软的身躯瘫陷在轮椅中,像一支在高温中变软且即将熔化的蜡烛。轮椅终于驶上了祭坛,在空旷的圆面上驶到了排险者面前。这时,太阳落下了一段时间,暗蓝色的天空中有零星的星星出现,祭坛周围的沙漠和草地模糊了。</p>
<p> “博士,您的问题?”排险者问,对霍金,他似乎并没有表示出比对其他人更多的尊重。他面带着毫无特点的微笑,听着博士轮椅上的扩音器中发出的呆板的电子声音:“宇宙的目的是什么?”</p>
<p> 天空中没有答案出现,排险者脸上的微笑消失了,他的双眼中掠过了一丝不易觉察的恐慌。</p>
<p> “先生?”霍金问。</p>
<p> 仍是沉默,天空仍是一片空旷,在地球的几缕薄云后面,宇宙的群星正在涌现。</p>
<p> “先生?”霍金又问。</p>
<p> “博士,出口在您后面。”排险者说。</p>
<p> “这是答案吗?”</p>
<p> 排险者摇摇头:“我是说您可以回去了。”</p>
<p> “你不知道?”排险者点点头说:“我不知道。”这时。他的面容第一次不仅是一个人类符号。一阵悲哀的黑云涌上这张脸,这悲哀表现得那样生动和富有个性,这时谁也不怀疑他是一个人,而且是一个最平常因而最不平常的普通人。</p>
<p> “我怎么知道。”排险者喃喃地说。</p>
<p><strong>尾声</strong></p>
<p> 十五年之后的一个夜晚,在已被变成草原的昔日的塔克拉玛干沙漠上,有一对母女正在交谈。母亲四十多岁,但白发已过早在出现在她的双鬃,从那饱经风霜的双眼中透出的,除了忧伤就是疲倦。女儿是一位苗条的少女,大而清澈的双眸中映着晶莹的星光。</p>
<p> 母亲在柔软的草地上坐下来,两眼失神地看着模糊的地平线说:“文文,你当年报考你爸爸母校的物理系,现在又要攻读量子引力专业的博士学位,妈都没拦你。你可以成为一名理论物理家,甚至可以把这门学科当做自己惟一的精神寄托。但,文文,妈求你了,千万不要越过那条线啊!”</p>
<p> 文文仰望着灿烂的银河,说:“妈妈,你能想像,这一切都来自于二百亿年前一个没有大小的奇点吗?宇宙早就越过那条线了。”</p>
<p> 方琳站起来,抓着女儿的肩膀说:“孩子,求你别这样!”</p>
<p> 文文双眼仍凝视着星空,一动不动。</p>
<p> “文文,你在听妈妈说话吗?你怎么了?”方琳摇晃着女儿,文文的目光仍被星海吸住收不回来,她盯着群星问:“妈妈,宇宙的目的是什么?”</p>
<p> “啊……不——”方琳彻底崩溃了,又跌坐在草地上,双手捂着脸抽泣着,“孩子,别,别这样!”</p>
<p> 文文终于收回了目光,蹲下来扶着妈妈的双肩,轻声问道:“那么,妈妈,人生的目的是什么?”</p>
<p> 这个问题像一块冰,使方琳灼烧的心立刻冷了下来。她扭头看了女儿一眼,然后看着远方深思。十五年前,就在她看替的那个方向,曾矗立过真理祭坛,再远些,爱因斯坦赤道曾穿过沙漠。</p>
<p> 微风吹来,草海上涌起道道波纹,仿佛是星空下无际的骚动的人海,向整个宇宙无声地歌唱着。</p>
<p> “不知道,我怎么知道呢?”方琳喃喃地说。</p>
搭建本地 DNS 缓存
https://pxx.io/2014/05/24/dnsmasq
2014-05-24T00:00:00+08:00
<p>搭建本地 DNS 缓存的好处有很多:</p>
<ol>
<li>加快 DNS 解析速度</li>
<li>防止 DNS 污染</li>
<li>屏蔽某些网站</li>
</ol>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装-dnsmasq">安装 Dnsmasq</h2>
<h3 id="arch-linux">Arch Linux</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> dnsmasq
</code></pre></div></div>
<h3 id="debian">Debian</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>dnsmasq
</code></pre></div></div>
<h2 id="配置-dnsmasq">配置 Dnsmasq</h2>
<p>编辑<code class="highlighter-rouge">/etc/dnsmasq.conf</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">no-resolv</span>
<span class="err">no-hosts</span>
<span class="py">cache-size</span><span class="p">=</span><span class="s">2048</span>
<span class="py">server</span><span class="p">=</span><span class="s">8.8.8.8</span>
<span class="py">serve</span><span class="p">=</span><span class="s">114.114.114.114</span>
</code></pre></div></div>
<h2 id="启动服务">启动服务</h2>
<h3 id="arch-linux-1">Arch Linux</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>dnsmasq.service
<span class="nb">sudo </span>systemctl start dnsmasq.service
</code></pre></div></div>
<h3 id="debian-1">Debian</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service dnsmasq start
</code></pre></div></div>
<h2 id="测试-dnsmasq">测试 Dnsmasq</h2>
<p>用下面的命令测试 Dnsmasq 是否正常工作</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @localhost www.google.com
</code></pre></div></div>
<p>正常的话应有类似下面的输出</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; <<>> DiG 9.9.2-P2 <<>> @localhost www.google.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29369
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 51 IN A 173.194.127.113
www.google.com. 51 IN A 173.194.127.116
www.google.com. 51 IN A 173.194.127.114
www.google.com. 51 IN A 173.194.127.115
www.google.com. 51 IN A 173.194.127.112
;; AUTHORITY SECTION:
google.com. 544 IN NS ns1.google.com.
google.com. 544 IN NS ns3.google.com.
google.com. 544 IN NS ns4.google.com.
google.com. 544 IN NS ns2.google.com.
;; ADDITIONAL SECTION:
ns1.google.com. 578 IN A 216.239.32.10
ns2.google.com. 578 IN A 216.239.34.10
ns3.google.com. 578 IN A 216.239.36.10
ns4.google.com. 578 IN A 216.239.38.10
;; Query time: 1 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat May 24 20:48:11 2014
;; MSG SIZE rcvd: 259
</code></pre></div></div>
<h2 id="修改系统默认-dns-服务器">修改系统默认 DNS 服务器</h2>
<h3 id="arch-linux-2">Arch Linux</h3>
<p>编辑 <code class="highlighter-rouge">/etc/resolvconf.conf</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">name_servers</span><span class="p">=</span><span class="s">127.0.0.1</span>
</code></pre></div></div>
<h3 id="debian-2">Debian</h3>
<p>编辑<code class="highlighter-rouge">/etc/resolv.conf</code>:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">nameserver</span> <span class="err">127.0.0.1</span>
</code></pre></div></div>
计算 e
https://pxx.io/2014/05/24/calc-e
2014-05-24T00:00:00+08:00
<!--more-->
<p><a id="more"></a></p>
<h2 id="计算公式">计算公式</h2>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
e & = \sum_{i = 0} ^ \infty {\frac{1}{i!}} \\
& = 1 + \frac{1}{1} + \frac{1}{1 \cdot 2} + \frac{1}{1 \cdot 2 \cdot 3} + \ldots
\end{align} %]]></script>
<p>取近似值</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
e & \approx \sum_{i = 0} ^ n {\frac{1}{i!}} \\
& = 1 + \frac{1}{1} + \frac{1}{1 \cdot 2} + \frac{1}{1 \cdot 2 \cdot 3} + \ldots + \frac{1}{1 \cdot 2 \cdot 3 \cdot \ldots \cdot n} \\
& = 1 + \frac{1}{1}(1 + \frac{1}{2}(1 + \frac{1}{3}(1 + \ldots (1 + \frac{1}{n}) \ldots )))
\end{align} %]]></script>
<p>该公式可以方便地用迭代法实现,代码如下</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">sum</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span> <span class="n">i</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">sum</span> <span class="o">/=</span> <span class="n">i</span><span class="p">;</span>
<span class="n">sum</span> <span class="o">+=</span> <span class="mf">1.0</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%1.15lf</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">sum</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>程序运行结果为</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gcc <span class="nt">-o</span> pi pi.c
./pi
2.718281828459045
</code></pre></div></div>
<h2 id="高精度实现">高精度实现</h2>
<p>高精度实现的代码如下</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
</span>
<span class="cp">#define ARRAY_SIZE 2502
#define ITERATIONS 5000
</span>
<span class="kt">int</span> <span class="n">e</span><span class="p">[</span><span class="n">ARRAY_SIZE</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">;</span>
<span class="c1">// e = 1.0;</span>
<span class="n">e</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="n">ITERATIONS</span><span class="p">;</span> <span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// e /= i;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">ARRAY_SIZE</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">e</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">e</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">%</span> <span class="n">i</span> <span class="o">*</span> <span class="mi">10000</span><span class="p">;</span>
<span class="n">e</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">/=</span> <span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// e += 1.0;</span>
<span class="n">e</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1000</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">2500</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%04d"</span><span class="p">,</span> <span class="n">e</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="误差分析">误差分析</h2>
<h3 id="截断误差">截断误差</h3>
<p>截断误差</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon _1 & = \frac{e^\theta}{(n+1)!} \\
& < \frac{e}{(n+1)!}
\end{align} %]]></script>
<h3 id="舍入误差">舍入误差</h3>
<p>设数组e的大小为k+1,则每次运算的舍入误差不超过$\frac{1}{10^{4k}}$,则多次运算积累的舍入误差</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon _2 & < \frac{1}{10^{4k}} \cdot n \\
& = \frac{n}{10^{4k}}
\end{align} %]]></script>
<h3 id="参数选取">参数选取</h3>
<p>若要计算$\pi$的前N位有效数字,须满足</p>
<script type="math/tex; mode=display">% <![CDATA[
\epsilon = \epsilon _ 1 + \epsilon _ 2 < \frac{1}{10^N} %]]></script>
<p>又</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon & = \epsilon _ 1 + \epsilon _ 2 \\
& < \frac{e}{(n+1)!} + \frac{n}{10^{4k}}
\end{align} %]]></script>
<p>故取n和k满足下式即可</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{e}{(n+1)!} + \frac{n}{10^{4k}} < \frac{1}{10^N} %]]></script>
<p>不妨取</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{e}{(n+1)!} < \frac{1}{10^{N+1}} \\
\frac{n}{10^{4k}} < \frac{1}{10^{N+1}} %]]></script>
<p>取</p>
<script type="math/tex; mode=display">n > N</script>
<script type="math/tex; mode=display">k > \frac{N + 1 + lg(n)}{4} = \frac{N + 1 + lg(N)}{4}</script>
Debian 安装配置 GoAgent
https://pxx.io/2014/05/20/debian-goagent
2014-05-20T00:00:00+08:00
<p>GoAgent 是用 Python 开发的代理软件,可以用来翻(he)墙(xie)。注意,这不是完整的安装教程。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="安装">安装</h2>
<h3 id="安装依赖">安装依赖</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>python python-dev python-pip libffi-dev libssl-dev
</code></pre></div></div>
<p>安装<code class="highlighter-rouge">gevent</code>、<code class="highlighter-rouge">python-openssl</code>、<code class="highlighter-rouge">pycrypto</code>、<code class="highlighter-rouge">dnslib</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pip <span class="nb">install </span>gevent <span class="nt">--upgrade</span>
<span class="nb">sudo </span>pip <span class="nb">install </span>pycrypto <span class="nt">--upgrade</span>
<span class="nb">sudo </span>pip <span class="nb">install </span>pyOpenSSL <span class="nt">--upgrade</span>
<span class="nb">sudo </span>pip <span class="nb">install </span>dnslib <span class="nt">--upgrade</span>
</code></pre></div></div>
<h3 id="安装goagent-3116">安装GoAgent 3.1.16</h3>
<p>编辑<code class="highlighter-rouge">install-goagent.sh</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="c">#</span>
<span class="c"># This script is used to install/uninstall goagent.</span>
<span class="c">#</span>
<span class="nb">set</span> <span class="nt">-e</span>
usage<span class="o">()</span> <span class="o">{</span>
<span class="nb">echo</span> <span class="s2">"Usage: </span><span class="si">$(</span><span class="nb">basename</span> <span class="nv">$0</span><span class="si">)</span><span class="s2">"</span>
<span class="nb">echo</span> <span class="s2">" -h, --help Show this help"</span>
<span class="nb">echo</span> <span class="s2">" -i, --install Install GoAgent"</span>
<span class="nb">echo</span> <span class="s2">" -u, --uninstall Uninstall GoAgent"</span>
<span class="o">}</span>
<span class="nv">VERSION</span><span class="o">=</span>3.1.16
<span class="nv">PREFIX</span><span class="o">=</span><span class="s2">"/usr"</span>
<span class="nv">DISTDIR</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span><span class="s2">/share/goagent"</span>
_install<span class="o">()</span> <span class="o">{</span>
<span class="nb">local </span><span class="nv">TMPDIR</span><span class="o">=</span><span class="si">$(</span><span class="nb">mktemp</span> <span class="nt">-d</span> /tmp/goagent-XXXXXXXX<span class="si">)</span>
<span class="nb">pushd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">TMPDIR</span><span class="k">}</span><span class="s2">"</span> <span class="o">></span>/dev/null
<span class="nb">echo</span> <span class="s2">"Downloading GoAgent..."</span>
wget <span class="nt">-q</span> <span class="s2">"https://github.com/goagent/goagent/archive/v</span><span class="k">${</span><span class="nv">VERSION</span><span class="k">}</span><span class="s2">.tar.gz"</span>
<span class="nb">echo</span> <span class="s2">"Installing..."</span>
<span class="nb">tar</span> <span class="nt">-zxf</span> <span class="s2">"v</span><span class="k">${</span><span class="nv">VERSION</span><span class="k">}</span><span class="s2">.tar.gz"</span>
<span class="nb">cd</span> <span class="s2">"goagent-</span><span class="k">${</span><span class="nv">VERSION</span><span class="k">}</span><span class="s2">/"</span>
<span class="nb">install</span> <span class="nt">-Dm755</span> <span class="s2">"local/proxy.py"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/goagent"</span>
<span class="nb">install</span> <span class="nt">-Dm755</span> <span class="s2">"local/dnsproxy.py"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/dnsproxy.py"</span>
<span class="nb">install</span> <span class="nt">-Dm644</span> <span class="s2">"local/proxy.pac"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/proxy.pac"</span>
<span class="nb">install</span> <span class="nt">-Dm644</span> <span class="s2">"local/cacert.pem"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/cacert.pem"</span>
<span class="nb">install</span> <span class="nt">-Dm644</span> <span class="s2">"local/dnslib-0.8.3.egg"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/dnslib-0.8.3.egg"</span>
<span class="k">if</span> <span class="o">[</span> <span class="nt">-f</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/goagent.ini"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span><span class="nb">mv</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">"</span>/local/goagent.ini<span class="o">{</span>,.old<span class="o">}</span>
<span class="nb">mv</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">"</span>/local/goagent.user.ini<span class="o">{</span>,.old<span class="o">}</span>
<span class="k">fi
</span><span class="nb">install</span> <span class="nt">-Dm644</span> <span class="s2">"local/proxy.ini"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/goagent.ini"</span>
<span class="nb">install</span> <span class="nt">-Dm644</span> <span class="s2">"/dev/null"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/local/goagent.user.ini"</span>
<span class="nb">cp</span> <span class="nt">-r</span> <span class="s2">"server"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/"</span>
<span class="nb">rm</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">/server/uploader.bat"</span>
<span class="nb">popd</span> <span class="o">></span>/dev/null
<span class="nb">rm</span> <span class="nt">-rf</span> <span class="s2">"</span><span class="k">${</span><span class="nv">TMPDIR</span><span class="k">}</span><span class="s2">"</span>
<span class="nb">echo</span> <span class="s2">"Done!"</span>
<span class="o">}</span>
_uninstall<span class="o">()</span> <span class="o">{</span>
<span class="nb">echo</span> <span class="s2">"Uninstalling GoAgent..."</span>
<span class="nb">rm</span> <span class="nt">-rf</span> <span class="s2">"</span><span class="k">${</span><span class="nv">DISTDIR</span><span class="k">}</span><span class="s2">"</span>
<span class="nb">echo</span> <span class="s2">"Done!"</span>
<span class="o">}</span>
<span class="c"># 无命令行参数时,显示帮助并退出</span>
<span class="o">[[</span> <span class="s2">"$#"</span> <span class="nt">-eq</span> 0 <span class="o">]]</span> <span class="o">&&</span> usage <span class="o">&&</span> <span class="nb">exit </span>0
<span class="nv">TEMP</span><span class="o">=</span><span class="si">$(</span>getopt <span class="nt">-o</span> hiu <span class="nt">-l</span> <span class="s2">"help"</span>,<span class="s2">"install"</span>,<span class="s2">"uninstall"</span> <span class="nt">-n</span> <span class="si">$(</span><span class="nb">basename</span> <span class="nv">$0</span><span class="si">)</span> <span class="nt">--</span> <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span><span class="si">)</span>
<span class="o">[[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]]</span> <span class="o">&&</span> <span class="nb">exit </span>1
<span class="nb">eval set</span> <span class="nt">--</span> <span class="s2">"</span><span class="nv">$TEMP</span><span class="s2">"</span>
<span class="k">while</span> :<span class="p">;</span> <span class="k">do
case</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="k">in</span>
<span class="nt">-h</span><span class="p">|</span><span class="nt">--help</span><span class="p">)</span>
usage
<span class="nb">exit </span>0
<span class="p">;;</span>
<span class="nt">-i</span><span class="p">|</span><span class="nt">--install</span><span class="p">)</span>
_install
<span class="nb">exit </span>0
<span class="p">;;</span>
<span class="nt">-u</span><span class="p">|</span><span class="nt">--uninstall</span><span class="p">)</span>
_uninstall
<span class="nb">exit </span>0
<span class="p">;;</span>
<span class="nt">--</span><span class="p">)</span>
<span class="nb">shift
break</span>
<span class="p">;;</span>
<span class="k">esac</span>
<span class="k">done
</span><span class="nb">exit </span>0
</code></pre></div></div>
<p>然后执行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">chmod</span> +x install-goagent.sh
<span class="nb">sudo</span> ./install-goagent.sh
</code></pre></div></div>
<h2 id="服务器端">服务器端</h2>
<p>注册Google Appengine并创建appid。具体过程略。</p>
<p>使用下面的命令上传:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>python /usr/share/goagent/server/uploader.zip
</code></pre></div></div>
<h2 id="客户端">客户端</h2>
<h3 id="配置goagent">配置GoAgent</h3>
<p>编辑<code class="highlighter-rouge">/usr/share/goagent/local/goagent.user.ini</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[gae]</span>
<span class="py">appid</span> <span class="p">=</span> <span class="s">****</span>
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/usr/share/goagent/local/goagent.ini</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[listen]</span>
<span class="py">ip</span> <span class="p">=</span> <span class="s">0.0.0.0</span>
<span class="py">port</span> <span class="p">=</span> <span class="s">8080</span>
</code></pre></div></div>
<h3 id="配置goagent开机自启动">配置GoAgent开机自启动</h3>
<p>编辑<code class="highlighter-rouge">/etc/rc.local</code>,添加:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">nohup </span>python /usr/share/goagent/local/goagent <span class="o">></span>/dev/null 2>&1 &
</code></pre></div></div>
<h2 id="浏览器代理配置">浏览器代理配置</h2>
<p>略</p>
计算 π
https://pxx.io/2014/05/20/calc-pi
2014-05-20T00:00:00+08:00
<!--more-->
<p><a id="more"></a></p>
<h2 id="计算公式">计算公式</h2>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\frac{\pi}{2} & = \sum_{i = 0} ^ \infty {\frac{i!}{(2i+1)!!}} \\
& = 1 + \frac{1}{3} + \frac{1 \cdot 2}{3 \cdot 5} + \frac{1 \cdot 2 \cdot 3}{3 \cdot 5 \cdot 7} + \ldots
\end{align} %]]></script>
<p>取近似值</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\frac{\pi}{2} & \approx \sum_{i = 0} ^ n {\frac{i!}{(2i+1)!!}} \\
& = 1 + \frac{1}{3} + \frac{1 \cdot 2}{3 \cdot 5} + \frac{1 \cdot 2 \cdot 3}{3 \cdot 5 \cdot 7} + \ldots + \frac{1 \cdot 2 \cdot 3 \cdot \ldots \cdot n}{3 \cdot 5 \cdot 7 \cdot \ldots \cdot (2n+1)} \\
& = 1 + \frac{1}{3}(1 + \frac{2}{5}(1 + \frac{3}{7}(1 + \ldots (1 + \frac{n}{2n+1}) \ldots )))
\end{align} %]]></script>
<p>即</p>
<script type="math/tex; mode=display">\pi \approx 2 + \frac{1}{3} \cdot (2 + \frac{2}{5} \cdot (2 + \frac{3}{7} \cdot (2 + \ldots (2 + \frac{n}{2n+1} \cdot 2) \ldots )))</script>
<p>该公式可以方便地用迭代法实现,代码如下</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">sum</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span> <span class="n">i</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">sum</span> <span class="o">=</span> <span class="n">sum</span> <span class="o">*</span> <span class="n">i</span> <span class="o">/</span> <span class="p">(</span><span class="n">i</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">sum</span> <span class="o">+=</span> <span class="mf">2.0</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%1.15lf</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">sum</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>程序运行结果为</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gcc <span class="nt">-o</span> pi pi.c
./pi
3.141592653589793
</code></pre></div></div>
<h2 id="高精度实现">高精度实现</h2>
<p>高精度实现的代码如下</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
</span>
<span class="cp">#define ARRAY_SIZE 2502
#define ITERATIONS 33223
</span>
<span class="kt">int</span> <span class="n">pi</span><span class="p">[</span><span class="n">ARRAY_SIZE</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">;</span>
<span class="c1">// pi = 2.0;</span>
<span class="n">pi</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="n">ITERATIONS</span><span class="p">;</span> <span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// pi *= i;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="n">ARRAY_SIZE</span><span class="p">;</span> <span class="n">j</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">*=</span> <span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="n">ARRAY_SIZE</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">></span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">--</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">/</span> <span class="mi">10000</span><span class="p">;</span>
<span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">%=</span> <span class="mi">10000</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// pi /= (i * 2 + 1);</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">ARRAY_SIZE</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pi</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10000</span><span class="p">;</span>
<span class="n">pi</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">/=</span> <span class="p">(</span><span class="n">i</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// pi += 2.0;</span>
<span class="n">pi</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">2000</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">2500</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%04d"</span><span class="p">,</span> <span class="n">pi</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="误差分析">误差分析</h2>
<h3 id="截断误差">截断误差</h3>
<p>易得</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\frac{i!}{(2i+1)!!} & = \frac{1 \cdot 2 \cdot \ldots \cdot i}{3 \cdot 5 \cdot \ldots \cdot (2i+1)} \\
& < \frac{1}{2^i}
\end{align} %]]></script>
<p>所以截断误差</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon _1 & < \sum_{i=n+1}^\infty\frac{1}{2^{i+1}} \\
& = \frac{1}{2^n} \\
& = \frac{1}{10^{n \cdot lg 2}}
\end{align} %]]></script>
<h3 id="舍入误差">舍入误差</h3>
<p>设数组pi的大小为k+1,则每次运算的舍入误差不超过$\frac{1}{10^{4k}}$,则多次运算积累的舍入误差</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon _2 & < \frac{1}{10^{4k}} \cdot n \\
& = \frac{n}{10^{4k}}
\end{align} %]]></script>
<h3 id="参数选取">参数选取</h3>
<p>若要计算$\pi$的前N位有效数字,须满足</p>
<script type="math/tex; mode=display">% <![CDATA[
\epsilon = \epsilon _ 1 + \epsilon _ 2 < \frac{1}{10^N} %]]></script>
<p>又</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
\epsilon & = \epsilon _ 1 + \epsilon _ 2 \\
& < \frac{1}{10^{n \cdot lg 2}}+ \frac{n}{10^{4k}}
\end{align} %]]></script>
<p>故取n和k满足下式即可</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{1}{10^{n \cdot lg 2}} + \frac{n}{10^{4k}} < \frac{1}{10^N} %]]></script>
<p>不妨取</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{1}{10^{n \cdot lg 2}} < \frac{1}{10^{N+1}} \\
\frac{n}{10^{4k}} < \frac{1}{10^{N+1}} %]]></script>
<p>取</p>
<script type="math/tex; mode=display">n > \frac{N + 1}{lg 2}</script>
<script type="math/tex; mode=display">k > \frac{N + 1 + lg(n)}{4} = \frac{N + 1 + lg(\frac{N + 1}{lg 2})}{4}</script>
在 Debian x86_64 上配置 Arch Linux ARM 分布式交叉编译环境
https://pxx.io/2014/05/15/cross-compiling
2014-05-15T00:00:00+08:00
<p>树莓派编译软件比较慢,最好用交叉编译的方法来加速编译过程。下面在安装了Debian 7.0的VPS上配置交叉编译环境,用于辅助树莓派编译软件包。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="客户端配置">客户端配置</h2>
<p>下面的操作均在Debian x86_64上执行,需要配置交叉编译工具链和Distcc客户端</p>
<h3 id="使用预构建工具链">使用预构建工具链</h3>
<p>可以直接下载Arch Linux ARM团队使用的工具链</p>
<p><a href="http://archlinuxarm.org/builder/xtools/x-tools6h.tar.xz">ARMv6l toolcanin</a> (9cbdc2c73f8065b189c12b8c0bb400bc)</p>
<h3 id="自行构建">自行构建</h3>
<h4 id="编译安装crosstool-ng">编译安装crosstool-ng</h4>
<p>安装编译crosstool-ng所需要的软件包</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>gperf bison flex texinfo gawk libtool automake libncurses5-dev
</code></pre></div></div>
<p>获取源代码并编译</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> cross/src
<span class="nb">cd </span>cross
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.19.0.tar.bz2
<span class="nb">tar</span> <span class="nt">-xjf</span> crosstool-ng-1.19.0.tar.bz2
<span class="nb">cd </span>crosstool-ng-1.19.0/
./configure <span class="nt">--prefix</span><span class="o">=</span>/home/your_user/cross
make
make <span class="nb">install</span>
</code></pre></div></div>
<h4 id="获取交叉编译工具配置">获取交叉编译工具配置</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /home/your_user/cross/bin
<span class="c"># 树莓派是ARMv6架构</span>
wget wget http://archlinuxarm.org/mirror/development/ct-ng/xtools-dotconfig-v6 <span class="nt">-O</span> .config
</code></pre></div></div>
<h4 id="构建交叉编译工具">构建交叉编译工具</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /home/your_user/cross/bin
./ct-ng <span class="nt">-j32</span> build
</code></pre></div></div>
<p>编译过程很费时,并且需要5~10GB的硬盘空间</p>
<h4 id="重命名文件">重命名文件</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="nb">cd</span> /home/puxx/x-tools6h/arm-unknown-linux-gnueabihf/bin/
<span class="k">for </span>file <span class="k">in</span> <span class="si">$(</span><span class="nb">ls</span><span class="si">)</span> <span class="p">;</span> <span class="k">do
if</span> <span class="o">[[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">file</span><span class="k">}</span><span class="s2">"</span> <span class="o">==</span> <span class="s2">"link"</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then
continue
fi
</span><span class="nb">ln</span> <span class="nt">-s</span> <span class="nv">$file</span> <span class="k">${</span><span class="nv">file</span><span class="p">#arm-unknown-linux-gnueabihf-</span><span class="k">}</span>
<span class="nb">ln</span> <span class="nt">-s</span> <span class="nv">$file</span> armv6l-unknown-linux-gnueabihf-<span class="k">${</span><span class="nv">file</span><span class="p">#arm-unknown-linux-gnueabihf-</span><span class="k">}</span>
<span class="k">done</span>
</code></pre></div></div>
<h3 id="配置distcc">配置distcc</h3>
<p>安装distcc</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>distcc
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/etc/init.d/distcc</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">PATH</span><span class="o">=</span>/home/puxx/x-tools6h/arm-unknown-linux-gnueabihf/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/etc/default/distcc</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">STARTDISTCC</span><span class="o">=</span><span class="s2">"true"</span>
<span class="nv">ALLOWEDNETS</span><span class="o">=</span><span class="s2">"****"</span> <span class="c"># 填上树莓派的IP地址</span>
</code></pre></div></div>
<p>启动distcc</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service distcc start
</code></pre></div></div>
<h2 id="主机配置">主机配置</h2>
<p>下面的操作在树莓派上执行</p>
<h3 id="安装distcc">安装distcc</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> distcc
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/etc/distcc/hosts</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">****</span> <span class="c"># 填上Debian VPS的IP地址或主机名
</span></code></pre></div></div>
<h3 id="配置makepkg">配置makepkg</h3>
<p>编辑<code class="highlighter-rouge">/etc/makepkg.conf</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">MAKEFLAGS</span><span class="o">=</span><span class="nt">-j32</span>
<span class="nv">BUILDENV</span><span class="o">=(</span>fakeroot distcc color <span class="o">!</span>ccache check <span class="o">!</span>sign<span class="o">)</span>
<span class="nv">DISTCC_HOSTS</span><span class="o">=</span><span class="s2">"****"</span> <span class="c"># 填上Debian VPS的IP地址或主机名</span>
</code></pre></div></div>
<h2 id="完成">完成</h2>
<p>以后在树莓派上使用makepkg编译软件包机会自动启用distcc分布式编译了</p>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://archlinuxarm.org/developers/distributed-compiling">Distributed Compiling</a></li>
<li><a href="http://archlinuxarm.org/developers/distcc-cross-compiling">Distcc Cross-Compiling</a></li>
</ol>
Debian 基本配置
https://pxx.io/2014/05/14/debian-init
2014-05-14T00:00:00+08:00
<p><a href="https://lug.ustc.edu.cn/">USTC LUG</a>提供了基于<a href="http://openvz.org/">OpenVZ</a>的<a href="https://en.wikipedia.org/wiki/Virtual_private_server">VPS</a>。我申请了一个Debian的虚拟机,下面做一些基本配置。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="初始化">初始化</h2>
<p>在Web控制页面选择安装Debian 7.0 wheezy,然后用ssh连入</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@yourdomain.com
</code></pre></div></div>
<h2 id="locale">Locale</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dpkg-reconfigure locales
</code></pre></div></div>
<p>选中</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">en_US.UTF-8</span> <span class="err">UTF-8</span>
<span class="err">zh_CN.GB18030</span> <span class="err">GB18030</span>
<span class="err">zh_CN.GBK</span> <span class="err">GBK</span>
<span class="err">zh_CN.UTF-8</span> <span class="err">UTF-8</span>
<span class="err">zh_CN</span> <span class="err">GB2312</span>
</code></pre></div></div>
<p>然后把<code class="highlighter-rouge">zh_CN.UTF-8</code>设为默认</p>
<h2 id="软件管理">软件管理</h2>
<p>更新系统</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt-get update
apt-get upgrade
</code></pre></div></div>
<p>安装软件</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt-get <span class="nb">install </span>vim git tree
<span class="nb">sudo </span>build-essential bash-completion
</code></pre></div></div>
<p>安装证书</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt-get <span class="nb">install </span>ca-certificates
</code></pre></div></div>
<h2 id="用户管理">用户管理</h2>
<p>新建用户<code class="highlighter-rouge">puxx</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>useradd <span class="nt">-m</span> <span class="nt">-g</span> <span class="nb">users</span> <span class="nt">-s</span> /bin/bash puxx
passwd puxx
</code></pre></div></div>
<p>让<code class="highlighter-rouge">puxx</code>可以执行<code class="highlighter-rouge">sudo</code></p>
<pre><code class="language-base">echo 'puxx ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/puxx
chmod 440 /etc/sudoers.d/puxx
</code></pre>
<p>禁用<code class="highlighter-rouge">root</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd <span class="nt">-l</span> root
</code></pre></div></div>
<h2 id="配置ssh-key">配置SSH Key</h2>
<p>切换为用户<code class="highlighter-rouge">puxx</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su puxx
</code></pre></div></div>
<p>保存SSH公钥</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> ~/.ssh
vim ~/.ssh/authorized_keys <span class="c"># 写入SSH公钥并保存</span>
<span class="nb">chmod </span>400 ~/.ssh/authorized_keys
<span class="nb">sudo </span>chattr +i ~/.ssh/authorized_keys
<span class="nb">sudo </span>chattr +i ~/.ssh
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/etc/ssh/sshd_config</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">PermitRootLogin</span> <span class="err">no</span>
<span class="err">PasswordAuthentication</span> <span class="err">no</span>
<span class="err">PermitEmptyPasswords</span> <span class="err">no</span>
</code></pre></div></div>
<p>重启ssh</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>service ssh restart
</code></pre></div></div>
<p>退出并重新连入ssh</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exit
</span>ssh puxx@puxx.6.freeshell.ustc.edu.cn
</code></pre></div></div>
自解压 bash 脚本
https://pxx.io/2014/05/02/self-extracting-script
2014-05-02T00:00:00+08:00
<p>首先,编辑<code class="highlighter-rouge">foo.sh</code>,写入以下内容,确保最后有个空白行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="nb">sed</span> <span class="s1">'1,/^#__END__$/d'</span> <span class="nv">$0</span> | <span class="nb">tar </span>zxf -
<span class="nb">exit</span>
<span class="c">#__END__</span>
</code></pre></div></div>
<!--more-->
<p><a id="more"></a></p>
<p>然后,把要打包的的文件用<code class="highlighter-rouge">tar</code>打成压缩包,并添加到脚本尾部,最后给脚本加上可执行属性</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar</span> <span class="nt">-zcf</span> foo.tar.gz foo
<span class="nb">cat </span>foo.tar.gz <span class="o">>></span> foo.sh
<span class="nb">chmod</span> +x foo.sh
</code></pre></div></div>
<p>如果要使用<code class="highlighter-rouge">xz</code>压缩,则脚本、需要执行的命令如下</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>
<span class="nb">sed</span> <span class="s1">'1,/^#__END__$/d'</span> <span class="nv">$0</span> | <span class="nb">tar </span>Jxf -
<span class="nb">exit</span>
<span class="c">#__END__</span>
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar</span> <span class="nt">-Jcf</span> foo.tar.xz foo
<span class="nb">cat </span>foo.tar.xz <span class="o">>></span> foo.sh
<span class="nb">chmod</span> +x foo.sh
</code></pre></div></div>
SSH 安全防护
https://pxx.io/2014/04/27/protect-ssh
2014-04-27T00:00:00+08:00
<p>SSH(Secure Shell)常用来用来远程访问主机(比如树莓派),安全问题十分重要。下面总结了一些SSH安全防护措施。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="禁止root登陆">禁止root登陆</h2>
<p>使用<code class="highlighter-rouge">root</code>登陆是不必要、有风险的,因此有必要禁止<code class="highlighter-rouge">root</code>登陆。有两种方法:</p>
<ol>
<li>
<p>禁用<code class="highlighter-rouge">root</code>用户</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo passwd -l root
</code></pre></div> </div>
</li>
<li>
<p>只禁止通过ssh登陆<code class="highlighter-rouge">root</code></p>
<p>编辑<code class="highlighter-rouge">/etc/ssh/sshd_config</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> PermitRootLogin no
</code></pre></div> </div>
</li>
</ol>
<h2 id="更改ssh使用的端口">更改ssh使用的端口</h2>
<p>ssh默认使用端口22,很容易被端口扫描软件发现,可以改成其他端口。编辑<code class="highlighter-rouge">/etc/ssh/sshd_config</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Port</span> <span class="err">12138</span>
</code></pre></div></div>
<h2 id="只允许指定的ip登陆ssh">只允许指定的IP登陆ssh</h2>
<p>有两种方法</p>
<ol>
<li>
<p>修改<code class="highlighter-rouge">/etc/hosts.allow</code>和<code class="highlighter-rouge">/etc/hosts.deny</code>
<code class="highlighter-rouge">/etc/hosts.allow</code>的内容</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sshd:192.168.12.2,192.168.12.3,129.168.1.1:allow
</code></pre></div> </div>
<p><code class="highlighter-rouge">/etc/hosts.deny</code>的内容</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sshd:ALL
</code></pre></div> </div>
</li>
<li>
<p>用<code class="highlighter-rouge">iptables</code>制定防火墙规则</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo iptables -A INPUT -p tcp -s 192.168.12.2 --dport 12138 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 192.168.12.3 --dport 12138 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 192.168.1.1 --dport 12138 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 12138 -j DROP
</code></pre></div> </div>
<p>可以编写systemd service文件开机自动执行这些命令。编辑<code class="highlighter-rouge">/usr/lib/systemd/system/ssh-firewall.service</code>,写入以下内容</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> [Unit]
Description=SSH Firewall
After=network.target
Wants=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/iptables -A INPUT -p tcp -s 192.168.12.2 --dport 12138 -j ACCEPT
ExecStart=/usr/bin/iptables -A INPUT -p tcp -s 192.168.12.3 --dport 12138 -j ACCEPT
ExecStart=/usr/bin/iptables -A INPUT -p tcp -s 192.168.1.1 --dport 12138 -j ACCEPT
ExecStart=/usr/bin/iptables -A INPUT -p tcp --dport 12138 -j DROP
ExecStop=/usr/bin/iptables -D INPUT -p tcp -s 192.168.12.2 --dport 12138 -j ACCEPT
ExecStop=/usr/bin/iptables -D INPUT -p tcp -s 192.168.12.3 --dport 12138 -j ACCEPT
ExecStop=/usr/bin/iptables -D INPUT -p tcp -s 192.168.1.1 --dport 12138 -j ACCEPT
ExecStop=/usr/bin/iptables -D INPUT -p tcp --dport 12138 -j DROP
[Install]
WantedBy=multi-user.target
</code></pre></div> </div>
<p>执行</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo systemctl enable ssh-firewall.service
</code></pre></div> </div>
</li>
</ol>
<h2 id="使用ssh密钥登陆">使用SSH密钥登陆</h2>
<p>使用密码来登陆ssh不仅麻烦,而且不安全,SSH密钥可以解决这个问题。</p>
<h3 id="生成ssh密钥">生成SSH密钥</h3>
<p>SSH密钥总是成对的,包括一个私钥,一个公钥。在<strong>电脑</strong>上使用下面的命令来生成一对密钥</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> ~/.ssh
ssh-keygen <span class="nt">-f</span> ~/.ssh/id_rsa
</code></pre></div></div>
<p>生成的公钥为<code class="highlighter-rouge">~/.ssh/id_rsa.pub</code>,私钥为<code class="highlighter-rouge">~/.ssh/id_rsa</code>,私钥务必要保密,公钥可以公开。</p>
<h3 id="把公钥复制到树莓派中">把公钥复制到树莓派中</h3>
<p>将公钥复制到树莓派的<code class="highlighter-rouge">/home/pi/.ssh/authorized_keys</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp <span class="nt">-P</span> 12138 ~/.ssh/id_rsa.pub pi@192.168.12.1:/home/pi/.ssh/authorized_keys
</code></pre></div></div>
<p>之后就可以免密码登入ssh了。</p>
<h3 id="禁止使用密码登陆">禁止使用密码登陆</h3>
<p>确定可以通过SSH密钥登陆后,可以禁止密码登陆,加强安全性。编辑<code class="highlighter-rouge">/etc/ssh/sshd_config</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">PasswordAuthentication</span> <span class="err">no</span>
<span class="err">PermitEmptyPasswords</span> <span class="err">no</span>
</code></pre></div></div>
<h3 id="防止公钥被意外修改">防止公钥被意外修改</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>chattr +i ~/.ssh/autorized_keys
<span class="nb">sudo </span>chattr +i ~/.ssh
</code></pre></div></div>
在 x86 上 chroot 到 Arch Linux ARM 的 rootfs
https://pxx.io/2014/04/23/rpi-cross-chroot
2014-04-23T00:00:00+08:00
<p><strong>主机:</strong> x86_64 Arch Linux</p>
<p><strong>目标rootfs:</strong> ARMv6, Arch Linux ARM, Raspberry Pi</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="获取-archlinux-arm-的-rootfs">获取 Archlinux ARM 的 rootfs</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>alarm-rootfs
wget http://mirrors.ustc.edu.cn/archlinuxarm/os/rpi/root.tar.xz
<span class="nb">tar</span> <span class="nt">-C</span> alarm-rootfs <span class="nt">-Jxf</span> root.tar.xz
wget http://mirrors.ustc.edu.cn/archlinuxarm/os/rpi/boot.tar.xz
<span class="nb">tar</span> <span class="nt">-C</span> alarm-rootfs/boot <span class="nt">-Jxf</span> boot.tar.xz
</code></pre></div></div>
<h2 id="获取静态编译的-qemu-arm">获取静态编译的 qemu-arm</h2>
<p>从 Ubuntu 的软件包 <code class="highlighter-rouge">qemu-user-static</code> 中提取</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget http://mirrors.ustc.edu.cn/ubuntu/pool/universe/q/qemu/qemu-user-static_2.0.0%2bdfsg-2ubuntu3_amd64.deb
ar <span class="nt">-x</span> qemu-user-static_2.0.0+dfsg-2ubuntu3_amd64.deb
<span class="nb">tar</span> <span class="nt">-Jxf</span> data.tar.xz
<span class="nb">mv </span>usr/bin/qemu-arm-static alarm-rootfs/usr/bin/
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">qemu-wrapper.c</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <string.h>
#include <unistd.h>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">envp</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">newargv</span><span class="p">[</span><span class="n">argc</span> <span class="o">+</span> <span class="mi">3</span><span class="p">];</span>
<span class="n">newargv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="n">newargv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s">"-cpu"</span><span class="p">;</span>
<span class="n">newargv</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="s">"cortex-a15"</span><span class="p">;</span>
<span class="n">memcpy</span><span class="p">(</span><span class="o">&</span><span class="n">newargv</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="o">&</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">argv</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">argc</span> <span class="o">-</span> <span class="mi">1</span><span class="p">));</span>
<span class="n">newargv</span><span class="p">[</span><span class="n">argc</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="k">return</span> <span class="n">execve</span><span class="p">(</span><span class="s">"/usr/bin/qemu-arm"</span><span class="p">,</span> <span class="n">newargv</span><span class="p">,</span> <span class="n">envp</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>用 gcc 静态编译并复制到 alarm-rootfs 中</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gcc <span class="nt">-static</span> <span class="nt">-O2</span> <span class="nt">-o</span> qemu-wrapper qemu-wrapper.c
<span class="nb">mv </span>qemu-wrapper alarm-rootfs/usr/bin/
</code></pre></div></div>
<h2 id="binfmt_misc">binfmt_misc</h2>
<p>binfmt_misc 用于在Linux上支持其他格式可执行文件(通过用户空间程序执行,如 wine、qemu)。</p>
<p>以 root 权限执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>modprobe binfmt_misc
<span class="nb">echo</span> <span class="s1">':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-wrapper:'</span> <span class="o">></span> /proc/sys/fs/binfmt_misc/register
</code></pre></div></div>
<h2 id="chroot">chroot</h2>
<p>安装 <code class="highlighter-rouge">arch-install-scripts</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> arch-install-scripts
</code></pre></div></div>
<p>执行 <code class="highlighter-rouge">chroot</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>arch-chroot alarm-rootfs /bin/bash
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="http://coldnew.github.io/blog/2013/06/27_dc09c.html">在 x86 下 chroot 到 ARM 平台的 rootfs</a></li>
<li><a href="http://coldnew.github.io/blog/2013/03/20_17398.html">binfmt_misc</a></li>
<li><a href="http://www.gentoo.org/proj/en/base/embedded/handbook/index.xml?part=1&chap=5">Compling with qemu user chroot</a></li>
</ol>
把树莓派改造成无线路由器
https://pxx.io/2014/04/16/rpi-router
2014-04-16T00:00:00+08:00
<p>这篇教程教你如何把树莓派改造成一个无线路由器,适用Arch Linux、Arch Linux ARM。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="目标">目标</h2>
<p>树莓派B型自带一个以太网口,作为WAN;USB无线网卡,作为WLAN。</p>
<ul>
<li><strong>IPv4</strong>
无线局域网配置为10.11.11.0/24,通过NAT连接互联网</li>
<li><strong>IPv6</strong>
配置IPv6-only网桥,通过桥接连接互联网</li>
</ul>
<h2 id="需求">需求</h2>
<ul>
<li>硬件
<ul>
<li>树莓派B型(安装Arch Linux ARM,能通过ssh连接)</li>
<li>USB无线网卡(芯片为RTL8188CUS)</li>
</ul>
</li>
<li>软件
<ul>
<li><a href="http://w1.fi/hostapd/">hostapd</a></li>
<li><a href="http://www.thekelleys.org.uk/dnsmasq/doc.html">dnsmasq</a></li>
<li><a href="http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge">bridge-utils</a></li>
<li><a href="http://ebtables.sourceforge.net/">ebtables</a></li>
<li><a href="http://www.netfilter.org/projects/iptables/index.html">iptables</a></li>
<li><a href="http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2">iproute2</a></li>
<li><a href="http://roy.marples.name/projects/dhcpcd/">dhcpcd</a></li>
</ul>
</li>
</ul>
<p>用ssh连入树莓派,下面的操作均在树莓派上执行。</p>
<h2 id="安装相关软件">安装相关软件</h2>
<p>安装软件</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> hostapd dnsmasq bridge-utils ebtables iptables iproute2 dhcpcd
</code></pre></div></div>
<p><strong>注意:</strong> 官方的<code class="highlighter-rouge">hostapd</code>不支持RTL8188CUS芯片的无线网卡,需要编译安装Realtek提供的hostapd才行,可安装AUR中的<a href="https://aur.archlinux.org/packages/hostapd-8192cu">hostapd-8192cu</a></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> hostapd-8192cu
</code></pre></div></div>
<p>树莓派编译比较慢,耐心等待即可。</p>
<h2 id="配置网卡接口名称">配置网卡接口名称</h2>
<p>很多发行版将以太网接口命名为ethX,无线网接口命名为wlanX。这样做有个明显的问题:当系统存在多个同类型的接口时,接口的名字可能是不固定的(如有时是eth0,有时是eth1)。为避免这样,下面给每个接口配置固定的名字。</p>
<p>编辑<code class="highlighter-rouge">/etc/udev/rules.d/10-network.rules</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="aa:bb:cc:dd:ee:ff", NAME="net0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ff:ee:dd:cc:bb:aa", NAME="ap0"
</code></pre></div></div>
<p>其中<code class="highlighter-rouge">aa:bb:cc:dd:ee:ff</code>替换为以太网卡的MAC地址,<code class="highlighter-rouge">ff:ee:dd:cc:bb:aa</code>替换为无线网卡的MAC地址。</p>
<p><strong>注意:</strong> 重启树莓派之前<strong>必须</strong>修改网络配置,否则可能无法再连入树莓派。</p>
<h2 id="配置ip地址">配置IP地址</h2>
<h3 id="net0使用dhcp动态获取ip地址">net0使用dhcp动态获取IP地址</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>dhcpcd@net0.service
</code></pre></div></div>
<p>或者</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>ifplugd@net0.service
</code></pre></div></div>
<h2 id="配置hostapd">配置hostapd</h2>
<p>编辑<code class="highlighter-rouge">/etc/hostapd/hostapd.conf</code>,根据需要修改<code class="highlighter-rouge">SSID</code>和<code class="highlighter-rouge">PASSWORD</code>。</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">interface</span><span class="p">=</span><span class="s">ap0</span>
<span class="py">ctrl_interface</span><span class="p">=</span><span class="s">/var/run/hostapd</span>
<span class="py">driver</span><span class="p">=</span><span class="s">rtl871xdrv</span>
<span class="py">hw_mode</span><span class="p">=</span><span class="s">g</span>
<span class="py">ieee80211n</span><span class="p">=</span><span class="s">1</span>
<span class="py">wmm_enabled</span><span class="p">=</span><span class="s">1</span>
<span class="py">ht_capab</span><span class="p">=</span><span class="s">[DSSS_CCK-40][MAX-AMSDU-7935][SMPS-STATIC][SHORT-GI-20][SHORT-GI-40][HT40-]</span>
<span class="py">channel</span><span class="p">=</span><span class="s">6</span>
<span class="py">supported_rates</span><span class="p">=</span><span class="s">480 540 720</span>
<span class="py">basic_rates</span><span class="p">=</span><span class="s">480 540 720</span>
<span class="py">ssid</span><span class="p">=</span><span class="s">SSID</span>
<span class="py">wpa</span><span class="p">=</span><span class="s">2</span>
<span class="py">wpa_passphrase</span><span class="p">=</span><span class="s">PASSWORD</span>
<span class="py">wpa_key_mgmt</span><span class="p">=</span><span class="s">WPA-PSK</span>
<span class="py">wpa_pairwise</span><span class="p">=</span><span class="s">TKIP</span>
<span class="py">rsn_pairwise</span><span class="p">=</span><span class="s">CCMP</span>
</code></pre></div></div>
<h2 id="配置dnsmasq">配置dnsmasq</h2>
<p>编辑<code class="highlighter-rouge">/etc/dnsmasq.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">interface</span><span class="p">=</span><span class="s">ap0</span>
<span class="err">bind-interfaces</span>
<span class="py">dhcp-range</span><span class="p">=</span><span class="s">10.11.11.1,10.11.11.254,1h</span>
<span class="py">dhcp-option</span><span class="p">=</span><span class="s">option:router,10.11.11.1</span>
</code></pre></div></div>
<h2 id="配置网络共享">配置网络共享</h2>
<p>启用内核转发,编辑<code class="highlighter-rouge">/etc/sysctl.d/10-net.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">net.ipv4.ip_forward</span> <span class="p">=</span> <span class="s">1</span>
</code></pre></div></div>
<p>编辑<code class="highlighter-rouge">/usr/lib/systemd/system/ap.service</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">Access Poing</span>
<span class="py">After</span><span class="p">=</span><span class="s">network.target</span>
<span class="py">Wants</span><span class="p">=</span><span class="s">network.target</span>
<span class="nn">[Service]</span>
<span class="py">Type</span><span class="p">=</span><span class="s">oneshot</span>
<span class="py">RemainAfterExit</span><span class="p">=</span><span class="s">yes</span>
<span class="py">ExecStartPre</span><span class="p">=</span><span class="s">/usr/bin/sleep 2</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/ip link set up dev ap0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/ip addr add 10.11.11.1/24 broadcast 10.11.11.255 dev ap0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/brctl addbr br0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/ip link set up dev br0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/ebtables -t broute -A BROUTING -p ! ipv6 -j DROP</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/brctl addif br0 net0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/brctl addif br0 ap0</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/systemctl start hostapd.service</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/systemctl start dnsmasq.service</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/systemctl stop dnsmasq.service</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/systemctl stop hostapd.service</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/ip link set down dev br0</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/brctl delbr br0</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/ebtables -t broute -D BROUTING -p ! ipv6 -j DROP</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/ip addr flush dev ap0</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/ip link set down dev ap0</span>
<span class="nn">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
</code></pre></div></div>
<p>开机启动</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>ap.service
</code></pre></div></div>
<p>开启 NAT,可以把下面的指令加入到自启动里</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>iptables <span class="nt">-t</span> nat <span class="nt">-A</span> POSTROUTING <span class="nt">-s</span> 10.11.11.0/24 <span class="nt">-j</span> MASQUERADE
</code></pre></div></div>
<h2 id="绑定mac地址">绑定MAC地址</h2>
<p>绑定MAC地址可以有效的防止蹭网。在<code class="highlighter-rouge">/etc/hostapd/hostapd.conf</code>中添加</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">macaddr_acl</span><span class="p">=</span><span class="s">1</span>
<span class="py">accept_mac_file</span><span class="p">=</span><span class="s">/etc/hostapd/hostapd.accept</span>
</code></pre></div></div>
<p>然后在 <code class="highlighter-rouge">/etc/hostapd/hostapd.accept</code> 中添加允许连接的设备,例如</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>01:23:45:67:89:01
ab:cd:ef:ab:cd:ef
</code></pre></div></div>
<h2 id="联网设备管理">联网设备管理</h2>
<h3 id="查看已连接的设备">查看已连接的设备</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /var/lib/misc/dnsmasq.leases
</code></pre></div></div>
<p>或者</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>hostapd_cli all_sta
</code></pre></div></div>
<h3 id="断开某个设备">断开某个设备</h3>
<p>首先查看设备的 MAC 地址,然后</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>hostapd_cli disassociate <MAC addr>
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ol>
<li><a href="https://wiki.archlinux.org/index.php/Software_access_point">Software Access Point</a></li>
</ol>
树莓派安装 Arch Linux ARM
https://pxx.io/2014/03/30/rpi-alarm
2014-03-30T00:00:00+08:00
<p>这是我在树莓派上安装 Arch Linux ARM 和简单配置的过程,仅供参考。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="所需配件">所需配件</h2>
<ol>
<li>树莓派B型</li>
<li>Micro-USB 连接线</li>
<li>SD 卡</li>
<li>5V 电源</li>
<li>网线</li>
</ol>
<h2 id="下载最新的系统">下载最新的系统</h2>
<ul>
<li><a href="http://mirrors.ustc.edu.cn/archlinuxarm/os/rpi/boot.tar.xz">boot.tar.gz</a></li>
<li><a href="http://mirrors.ustc.edu.cn/archlinuxarm/os/rpi/root.tar.xz">root.tar.gz</a></li>
</ul>
<h2 id="sd-卡分区">SD 卡分区</h2>
<p>把 SD 卡插在电脑上,分区表设为 MBR,创建三个分区</p>
<table>
<thead>
<tr>
<th>分区</th>
<th>大小</th>
<th>文件系统</th>
</tr>
</thead>
<tbody>
<tr>
<td>sdb1</td>
<td>100MiB</td>
<td>FAT32</td>
</tr>
<tr>
<td>sdb2</td>
<td>7GiB</td>
<td>ext4</td>
</tr>
<tr>
<td>sdb3</td>
<td>1GiB</td>
<td>swap</td>
</tr>
</tbody>
</table>
<h2 id="复制相关文件">复制相关文件</h2>
<p>首先挂载相应的分区</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mount /dev/sdb2 <span class="nt">-o</span> noatime,discard /mnt
<span class="nb">sudo mkdir</span> /mnt/boot
<span class="nb">sudo </span>mount /dev/sdb1 <span class="nt">-o</span> noatime /mnt/boot
</code></pre></div></div>
<p>解压文件到指定位置</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>bsdtar <span class="nt">-xpf</span> /path/to/root.tar.xz <span class="nt">-C</span> /mnt
<span class="nb">sudo </span>bsdtar <span class="nt">-xpf</span> /path/to/boot.tar.xz <span class="nt">-C</span> /mnt/boot
</code></pre></div></div>
<p>做一些必要的修改:</p>
<ol>
<li>
<p>编辑 <code class="highlighter-rouge">/mnt/etc/fstab</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> # /etc/fstab: static file system information
#
# <file system> <dir> <type> <options> <dump> <pass>
/dev/mmcblk0p2 / ext4 noatime,discard 0 1
/dev/mmcblk0p1 /boot vfat noatime 0 0
/dev/mmcblk0p3 none swap defaults,discard 0 0
</code></pre></div> </div>
</li>
<li>
<p>编辑 <code class="highlighter-rouge">/mnt/boot/cmdline.txt</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> avoid_safe_mode=1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=Y dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
</code></pre></div> </div>
</li>
</ol>
<p>最后卸载分区</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sync
sudo </span>umount /mnt/boot
<span class="nb">sudo </span>umount /mnt
<span class="nb">sync</span>
</code></pre></div></div>
<p>此时,SD卡中就安装好了 Arch Linux ARM 最小启动环境了。</p>
<h2 id="通过-ssh-连接树莓派">通过 ssh 连接树莓派</h2>
<p>树莓派的以太网接口默认配置成 DHCP 自动获取 IP 地址,开启 sshd 服务,<code class="highlighter-rouge">root</code> 密码为 <code class="highlighter-rouge">root</code>。</p>
<ol>
<li>
<p>将电脑的以太网接口配置为局域网网关(假设接口名称为 enp7s0)</p>
<ol>
<li>
<p>安装 <code class="highlighter-rouge">dnsmasq</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo pacman -S dnsmasq
</code></pre></div> </div>
</li>
<li>
<p>编辑 <code class="highlighter-rouge">/etc/dnsmasq</code>,写入以下内容</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> interface=enp7s0
bind-interfaces
dhcp-range=192.168.1.1,192.168.1.254,255.255.255.0,24h
dhcp-option=option:router,192.168.1.1
</code></pre></div> </div>
</li>
<li>
<p>执行下面的命令</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo ip link set up dev enp7s0
sudo ip addr add 192.168.1.1/24 broadcast 192.168.1.255 dev enp7s0
sudo systemctl start dnsmasq.service
</code></pre></div> </div>
</li>
</ol>
</li>
<li>
<p>将树莓派和电脑用网线连接起来,接通树莓派电源。此时,树莓派应该自动配置好 IP,和电脑处于同一个局域网了。用下面的命令查看树莓派的 IP 地址</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ip neigh show dev enp7s0
</code></pre></div> </div>
</li>
<li>
<p>假设树莓派地址为 <code class="highlighter-rouge">192.168.1.3</code>,用 <code class="highlighter-rouge">ssh</code> 登陆到树莓派</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ssh root@192.168.1.3
</code></pre></div> </div>
</li>
</ol>
<h2 id="配置树莓派">配置树莓派</h2>
<p>上面只是做了一些最基本的配置,还有许多工作要做。</p>
<h3 id="配置-pacman">配置 pacman</h3>
<p>编辑 <code class="highlighter-rouge">/etc/pacman.d/mirrorlist</code>,改为以下内容</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Server <span class="o">=</span> http://mirrors.ustc.edu.cn/archlinuxarm/<span class="nv">$arch</span>/<span class="nv">$repo</span>
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/pacman.conf</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CacheDir <span class="o">=</span> /tmp/pacman/pkg
</code></pre></div></div>
<p>更新系统</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-Syyu</span>
</code></pre></div></div>
<p>安装 <code class="highlighter-rouge">base</code>,<code class="highlighter-rouge">base-devel</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> <span class="nt">--needed</span> base base-devel
</code></pre></div></div>
<h3 id="配置-makepkg">配置 makepkg</h3>
<p>编辑 <code class="highlighter-rouge">/etc/makepkg.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">CFLAGS</span><span class="p">=</span><span class="s">"-mcpu=arm1176jzf-s -march=armv6zk -mtls-dialect=gnu2 -mfloat-abi=hard -mfpu=vfp -O2 -pipe"</span>
<span class="py">CXXFLAGS</span><span class="p">=</span><span class="s">"-mcpu=arm1176jzf-s -march=armv6zk -mtls-dialect=gnu2 -mfloat-abi=hard -mfpu=vfp -O2 -pipe"</span>
<span class="py">BUILDDIR</span><span class="p">=</span><span class="s">/tmp/makepkg</span>
</code></pre></div></div>
<h3 id="更新-linux内核">更新 linux内核</h3>
<p>树莓派的 Arch Linux ARM 默认使用的不是最新的内核,可以更新成最新的</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> linux-raspberrypi-latest
</code></pre></div></div>
<h3 id="用户管理">用户管理</h3>
<p>新建用户组 <code class="highlighter-rouge">sudo</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>groupadd <span class="nb">sudo</span>
</code></pre></div></div>
<p>新建一个用户 pi</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>useradd <span class="nt">-m</span> <span class="nt">-g</span> <span class="nb">users</span> <span class="nt">-s</span> /bin/bash pi
passwd pi
gpasswd <span class="nt">-a</span> pi <span class="nb">sudo</span>
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/sudoers</code> 以便新用户可以执行 <code class="highlighter-rouge">sudo</code>,将下面的行取消注释</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>%sudo <span class="nv">ALL</span><span class="o">=(</span>ALL:ALL<span class="o">)</span> ALL
</code></pre></div></div>
<p>禁用 <code class="highlighter-rouge">root</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>passwd <span class="nt">-l</span> root
</code></pre></div></div>
<p>注销 <code class="highlighter-rouge">root</code> 并以用户 <code class="highlighter-rouge">pi</code> 登陆</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exit
</span>ssh pi@192.168.1.3
</code></pre></div></div>
<h3 id="locale">Locale</h3>
<p>编辑<code class="highlighter-rouge">/etc/locale.gen</code>,将下面的行取消注释</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>en_US.UTF-8 UTF-8
zh_CN.GB18030 GB18030
zh_CN.GBK GBK
zh_CN.UTF-8 UTF-8
zh_CN GB2312
</code></pre></div></div>
<p>然后执行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>locale-gen
</code></pre></div></div>
<p>设置系统语言为 <code class="highlighter-rouge">zh_CN.UTF-8</code>,编辑 <code class="highlighter-rouge">/etc/locale.conf</code>,写入以下内容</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">LANG</span><span class="o">=</span>zh_CN.UTF-8
</code></pre></div></div>
<h3 id="时区">时区</h3>
<p>设置时区为 <code class="highlighter-rouge">Shanghai</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo rm</span> /etc/localtime
<span class="nb">sudo ln</span> <span class="nt">-s</span> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
</code></pre></div></div>
<h3 id="时间">时间</h3>
<p>树莓派没有硬件时钟,每次关机时间都会丢失,因此需要设置自动联网对时。安装 <code class="highlighter-rouge">ntp</code>,并启用自动对时</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> ntp
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>ntpd.service
</code></pre></div></div>
<h3 id="随机数生成器">随机数生成器</h3>
<p>安装 <code class="highlighter-rouge">rng-tools</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> rng-tools
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/conf.d/rng</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">RNGD_OPTS</span><span class="p">=</span><span class="s">"-o /dev/random -r /dev/hwrng"</span>
</code></pre></div></div>
<p>启动服务</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>rngd.service
</code></pre></div></div>
<h3 id="超频">超频</h3>
<p>编辑 <code class="highlighter-rouge">/boot/config.txt</code>,将下面的行取消注释</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">arm_freq</span><span class="p">=</span><span class="s">900</span>
<span class="py">core_freq</span><span class="p">=</span><span class="s">333</span>
<span class="py">sdram_freq</span><span class="p">=</span><span class="s">400</span>
<span class="py">over_voltage</span><span class="p">=</span><span class="s">2</span>
</code></pre></div></div>
<h3 id="启用硬件看门狗">启用硬件看门狗</h3>
<p>编辑 <code class="highlighter-rouge">/etc/modules-load.d/watchdog.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bcm2708_wdog
</code></pre></div></div>
<p>安装 <code class="highlighter-rouge">watchdog</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> watchdog
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/watchdog.conf</code></p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">watchdog-device</span> <span class="p">=</span> <span class="s">/dev/watchdog</span>
<span class="py">temperature-device</span> <span class="p">=</span> <span class="s">/sys/class/thermal/thermal_zone0/temp</span>
<span class="py">max-temperature</span> <span class="p">=</span> <span class="s">75000</span>
</code></pre></div></div>
<p>开机启动watchdog daemon</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>watchdog.service
</code></pre></div></div>
<h3 id="安装无线网卡驱动">安装无线网卡驱动</h3>
<p>买来的无线网卡用的芯片是 RTL8188CUS,需要自行安装驱动</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> dkms-8192cu
</code></pre></div></div>
<p>安装过程中需要编译内核模块,比较耗时,耐心等待即可。</p>
<h3 id="安装常用的软件">安装常用的软件</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> bash-completion vim yaourt goagent <span class="se">\</span>
youtube-dl transmission-cli bc tree <span class="se">\</span>
axel pkgfile git
yaourt <span class="nt">-S</span> tengine-dev
</code></pre></div></div>
<h3 id="关机重启">关机/重启</h3>
<p>关机</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>shutdown <span class="nt">-h</span> now
</code></pre></div></div>
<p>重启</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>reboot
</code></pre></div></div>
《最后的问题》 阿西莫夫
https://pxx.io/2014/03/22/the-last-question
2014-03-22T00:00:00+08:00
<p><em>注:</em> 译文来自人人网的一片日志,但源链接找不到了</p>
<p>The last question was asked for the first time, half in jest, on May 21, 2061, at a time when humanity first stepped into the light. The question came about as a result of a five-dollar bet over highballs, and it happened this way:</p>
<p>最后的问题第一次被半开玩笑地提出是在2061年的5月21日。那时人类文明刚刚步入曙光中。那个问题源起于酒酣之中五美元的一次打赌,它是这么发生的:</p>
<!--more-->
<p><a id="more"></a></p>
<p>Alexander Adell and Bertram Lupov were two of the faithful attendants of Multivac. As well as any human beings could, they knew what lay behind the cold, clicking, flashing face – miles and miles of face – of that giant computer. They had at least a vague notion of the general plan of relays and circuits that had long since grown past the point where any single human could possibly have a firm grasp of the whole.</p>
<p>亚历山大·阿代尔与贝特伦·卢泊夫是Multivac的两个忠实的管理员。像任何其他人一样,他们知道在那台巨大的计算机数英里冰冷、闪烁、滴答作响的面庞后藏着什么。那些电子回路早已发展到任何个别的人都无法完全掌握的地步,但他们至少对它的大致蓝图有个基本的概念。</p>
<p>Multivac was self-adjusting and self-correcting. It had to be, for nothing human could adjust and correct it quickly enough or even adequately enough. So Adell and Lupov attended the monstrous giant only lightly and superficially, yet as well as any men could. They fed it data, adjusted questions to its needs and translated the answers that were issued. Certainly they, and all others like them, were fully entitled to share in the glory that was Multivac’s.</p>
<p>Multivac能自我调节和自我修正。它必须具备这样的能力,因为没有人能足够快甚至足够好地对它进行调节和修正。所以实际上阿代尔与卢泊夫对这个庞然大物只进行一些非常轻松和表面的管理,任何其他人也都只能做到这一步。他们给它输送数据,根据它所需的格式修改问题,然后翻译给出的答案。当然,他们以及其他管理员们完全有资格分享属于Multivac的荣誉。</p>
<p>For decades, Multivac had helped design the ships and plot the trajectories that enabled man to reach the Moon, Mars, and Venus, but past that, Earth’s poor resources could not support the ships. Too much energy was needed for the long trips. Earth exploited its coal and uranium with increasing efficiency, but there was only so much of both.</p>
<p>几十年中,在Multivac的帮助下人类建造了宇宙飞船,计算出航行路径,从而得以登陆月球、火星和金星。但是更远的航行需要大量的能量,地球上可怜的资源不足以支持这些飞船。尽管人类不断地提高煤炭和核能的利用效率,但煤和铀都只有那么多。</p>
<p>But slowly Multivac learned enough to answer deeper questions more fundamentally, and on May 14, 2061, what had been theory, became fact.</p>
<p>但是慢慢地Multivac学会了如何从根本上解决某些深层次问题。2061年5月14日,理论成为了现实。</p>
<p>The energy of the sun was stored, converted, and utilized directly on a planet-wide scale. All Earth turned off its burning coal, its fissioning uranium, and flipped the switch that connected all of it to a small station, one mile in diameter, circling the Earth at half the distance of the Moon. All Earth ran by invisible beams of sunpower.</p>
<p>太阳的能量得到储存和转化,并能被全球规模地直接利用。整个地球熄灭了燃烧的煤炭,关闭了核反应炉,打开了连接到那个小小的太阳能空间站的开关——它直径一英里,在到月球的距离一半处环绕着地球。看不见的太阳的光束支撑着整个地球社会的运行。</p>
<p>Seven days had not sufficed to dim the glory of it and Adell and Lupov finally managed to escape from the public functions, and to meet in quiet where no one would think of looking for them, in the deserted underground chambers, where portions of the mighty buried body of Multivac showed. Unattended, idling, sorting data with contented lazy clickings, Multivac, too, had earned its vacation and the boys appreciated that. They had no intention, originally, of disturbing it.</p>
<p>七天还不足以暗淡这创举的光辉。阿代尔与卢泊夫总算逃脱了公众事务,悄悄地相聚在这个荒僻的地下室,谁也想不到他们会在这儿。在这里Multivac埋藏着的庞大身躯露出了一部分。它正独自闲暇地整理着数据,发出满足的、慵懒的滴答声——它也得到了假期。他们了解这一点,他们一开始并没打算打扰它。</p>
<p>They had brought a bottle with them, and their only concern at the moment was to relax in the company of each other and the bottle.</p>
<p>他们带来了一瓶酒。这会儿他们想做的只是一起在酒瓶的陪伴下放松放松。</p>
<p>“It’s amazing when you think of it,” said Adell. His broad face had lines of weariness in it, and he stirred his drink slowly with a glass rod, watching the cubes of ice slur clumsily about. “All the energy we can possibly ever use for free. Enough energy, if we wanted to draw on it, to melt all Earth into a big drop of impure liquid iron, and still never miss the energy so used. All the energy we could ever use, forever and forever and forever.”</p>
<p>“你想一想就会觉得很神奇,”阿代尔说。他宽阔的脸庞已有了疲倦的纹路。他慢慢地用玻璃棒搅动着酒,看着冰块笨拙地滑动。“从此我们所用的所有能量都是免费的。只要我们愿意,我们能把地球熔化成一颗液态大铁球——还能毫不在乎花掉的能量。够我们永远用下去的能量,永远、永远、永远。”</p>
<p>Lupov cocked his head sideways. He had a trick of doing that when he wanted to be contrary, and he wanted to be contrary now, partly because he had had to carry the ice and glassware. “Not forever,” he said.</p>
<p>卢泊夫将头歪向一边。这是当他想要反驳对方时的习惯动作,而他现在确实想要反驳,部分是因为他要负责拿着冰和杯子。他说:“不是永远。”</p>
<p>“Oh, hell, just about forever. Till the sun runs down, Bert.”</p>
<p>“哦去你的,差不多就是永远。直到太阳完蛋,老贝。”</p>
<p>“That’s not forever.”</p>
<p>“那就不是永远。”</p>
<p>“All right, then. Billions and billions of years. Ten billion, maybe. Are you satisfied?”</p>
<p>“好吧。几十亿年,可能一百亿年,满意了吧?”</p>
<p>Lupov put his fingers through his thinning hair as though to reassure himself that some was still left and sipped gently at his own drink. “Ten billion years isn’t forever.”</p>
<p>卢泊夫用手梳着他稀薄的头发,仿佛要确认还剩下一些。他缓缓地抿着自己的酒说,“一百亿年也不是永远。”</p>
<p>“Well, it will last our time, won’t it?”</p>
<p>“但对我们来说是够了,不是吗?”</p>
<p>“So would the coal and uranium.”</p>
<p>“煤和铀对我们来说也够了。”</p>
<p>“All right, but now we can hook up each individual spaceship to the Solar Station, and it can go to Pluto and back a million times without ever worrying about fuel. You can’t do that on coal and uranium. Ask Multivac, if you don’t believe me.</p>
<p>“好好好,但是现在我们能把宇宙飞船连接到太阳能电站,然后飞到冥王星又飞回来一百万次而不用担心燃料的事。靠煤和铀你没法办到。不信去问问Multivac。”</p>
<p>“I don’t have to ask Multivac. I know that.”</p>
<p>“我不用问它。我知道。”</p>
<p>“Then stop running down what Multivac’s done for us,” said Adell, blazing up, “It did all right.”</p>
<p>“那就不要小看Multivac为我们做的事,”阿代尔怒道,“它做得很好。”</p>
<p>“Who says it didn’t? What I say is that a sun won’t last forever. That’s all I’m saying. We’re safe for ten billion years, but then what?” Lupow pointed a slightly shaky finger at the other. “And don’t say we’ll switch to another sun.”</p>
<p>“谁说它做得不好?我是说太阳不能永远燃烧下去,我只是这个意思。我们在一百亿年内可以高枕无忧,但是然后呢?”卢泊夫用略微颤抖的手指指着对方,“不要说我们换另外一个太阳。”</p>
<p>There was silence for a while. Adell put his glass to his lips only occasionally, and Lupov’s eyes slowly closed. They rested.</p>
<p>片刻的沉默。阿代尔偶尔将酒杯放到唇边,而卢泊夫慢慢地闭上了眼睛。两人都在休息。</p>
<p>Then Lupov’s eyes snapped open. “You’re thinking we’ll switch to another sun when ours is done, aren’t you?”</p>
<p>然后卢泊夫突然睁开眼,“你在想当我们的太阳没了就换另外一个太阳,是吧?”</p>
<p>“I’m not thinking.”</p>
<p>“我没这么想。”</p>
<p>“Sure you are. You’re weak on logic, that’s the trouble with you. You’re like the guy in the story who was caught in a sudden shower and who ran to a grove of trees and got under one. He wasn’t worried, you see, because he figured when one tree got wet through, he would just get under another one.”</p>
<p>“你就是这么想的。你的逻辑不行,这就是你的问题。你就像故事里说的那个人一样,碰上了雨就跑到树林里躲在一棵树下。他可不担心,是吧,因为他以为当这棵树淋得太湿的时候他只要跑到另一棵树下就行。”</p>
<p>“I get it,” said Adell. “Don’t shout. When the sun is done, the other stars will be gone, too.”</p>
<p>“我明白了,”阿代尔说,“别嚷嚷。太阳完蛋了,其他的也都会完蛋,是吧。”</p>
<p>“Darn right they will,” muttered Lupov. “It all had a beginning in the original cosmic explosion, whatever that was, and it’ll all have an end when all the stars run down. Some run down faster than others. Hell, the giants won’t last a hundred million years. The sun will last ten billion years and maybe the dwarfs will last two hundred billion for all the good they are. But just give us a trillion years and everything will be dark. Entropy has to increase to maximum, that’s all.”</p>
<p>“完全正确,”卢泊夫嘟哝道,“一切都在起初那个宇宙大爆炸中有个开始,不管那到底是怎么回事。当所有的恒星都熄灭了,一切也都会有个结束。有的星星灭得比别的早。像那些该死的巨星维持不了一亿年。我们的太阳能持续一百亿年,矮星再怎么样最多也只有两千亿年。一万亿年后一切都是一片漆黑。熵必须增加到最大值,就是这样。”</p>
<p>“I know all about entropy,” said Adell, standing on his dignity.</p>
<p>“我非常明白什么是熵,”阿代尔维护着他的自尊。</p>
<p>“The hell you do.”</p>
<p>“你明白个屁。”</p>
<p>“I know as much as you do.”</p>
<p>“我跟你知道的一样多。”</p>
<p>“Then you know everything’s got to run down someday.”</p>
<p>“那你该知道某一天所有的东西都会耗光。”</p>
<p>“All right. Who says they won’t?”</p>
<p>“是是是。谁说它们不会呢?”</p>
<p>“You did, you poor sap. You said we had all the energy we needed, forever. You said ‘forever.’</p>
<p>“你说的,你这个糊涂虫。你说我们有永远用不完的能量。你说的‘永远’。”</p>
<p>It was Adell’s turn to be contrary. “Maybe we can build things up again someday,” he said.</p>
<p>现在轮到阿代尔反驳了。他说:“也许有一天我们能让一切从头开始。”</p>
<p>“Never.”</p>
<p>“绝不可能。”</p>
<p>“Why not? Someday.”</p>
<p>“为什么?总有那么一天的。”</p>
<p>“Never.”</p>
<p>“没有。”</p>
<p>“Ask Multivac.”</p>
<p>“问问Multivac。”</p>
<p>“You ask Multivac. I dare you. Five dollars says it can’t be done.”</p>
<p>“你去问Multivac。你敢吗?我赌五美元它说这不可能。”</p>
<p>Adell was just drunk enough to try, just sober enough to be able to phrase the necessary symbols and operations into a question which, in words, might have corresponded to this: Will mankind one day without the net expenditure of energy be able to restore the sun to its full youthfulness even after it had died of old age?</p>
<p>阿代尔刚刚醉到愿意一试,又刚刚足够清醒到能拼写出问问题需要的符号和算式。这个问题用文字来表达就是:人类是否有一天能不需要净损耗能量而在恒星衰竭之后将其恢复到全盛时期?</p>
<p>Or maybe it could be put more simply like this: How can the net amount of entropy of the universe be massively decreased?</p>
<p>或者更简明地这样说:怎样使宇宙的总熵大幅度地降低?</p>
<p>Multivac fell dead and silent. The slow flashing of lights ceased, the distant sounds of clicking relays ended.</p>
<p>Multivac陷入了静止和沉默。缓慢闪烁的灯光熄灭了,深处传来的电路的滴答声停止了。</p>
<p>Then, just as the frightened technicians felt they could hold their breath no longer, there was a sudden springing to life of the teletype attached to that portion of Multivac. Five words were printed: INSUFFICIENT DATA FOR MEANINGFUL ANSWER.</p>
<p>正当这两位被吓坏的技术员感到他们无法再屏住呼吸时,忽然间与Multivac相连的打字机开始运作起来。它打出几个字:数据不足,无法作答。</p>
<p>“No bet,” whispered Lupov. They left hurriedly.</p>
<p>“赌不成了。”卢泊夫悄声道。他们匆忙离开了。</p>
<p>By next morning, the two, plagued with throbbing head and cottony mouth, had forgotten the incident.</p>
<p>到了第二天早晨,两人头晕脑胀,口干舌燥,把这件事给忘了。</p>
<hr />
<p>Jerrodd, Jerrodine, and Jerrodette I and II watched the starry picture in the visiplate change as the passage through hyperspace was completed in its non-time lapse. At once, the even powdering of stars gave way to the predominance of a single bright shining disk, the size of a marble, centered on the viewing-screen.</p>
<p>贾诺德、贾诺汀和贾诺蒂I、贾诺蒂II注视着屏幕中变幻的星空影像。飞船在时间之外的一瞬中穿越了超时空,均匀分布的星群立刻被一个明亮的圆盘取代。它弹珠大小,占据着屏幕的中心。</p>
<p>“That’s X-23,” said Jerrodd confidently. His thin hands clamped tightly behind his back and the knuckles whitened.</p>
<p>“那就是X-23,”贾诺德自信地说。他紧握着的瘦削的手背在身后,指节发白。</p>
<p>The little Jerrodettes, both girls, had experienced the hyperspace passage for the first time in their lives and were self-conscious over the momentary sensation of insideoutness. They buried their giggles and chased one another wildly about their mother, screaming, “We’ve reached X-23 – we’ve reached X-23 – we’ve –”</p>
<p>两个小贾诺蒂都是女孩。她们一生中第一次经历超时空飞行,清晰地感到那种片刻的恶心。她们悄声地嘻笑着,疯狂地绕着她们的母亲互相追逐,一边尖叫:“我们到X-23了——我们到X-23了——我们——”</p>
<p><em>注:</em> 难以翻译的“超时空飞行”特有的恶心,大概是一种五脏六腑被翻出来的感觉吧。</p>
<p>“Quiet, children.” said Jerrodine sharply. “Are you sure, Jerrodd?”</p>
<p>“孩子们,别闹了!”贾诺汀严厉地说。“你确定吗,贾诺德?”</p>
<p>“What is there to be but sure?” asked Jerrodd, glancing up at the bulge of featureless metal just under the ceiling. It ran the length of the room, disappearing through the wall at either end. It was as long as the ship.</p>
<p>“有什么不确定的?”贾诺德瞟了一眼天花板上凸出的那块毫不起眼的金属。它从房间的一头延伸到另一头,两端埋入墙壁中。它和整个飞船一样长。</p>
<p>Jerrodd scarcely knew a thing about the thick rod of metal except that it was called a Microvac, that one asked it questions if one wished; that if one did not it still had its task of guiding the ship to a preordered destination; of feeding on energies from the various Sub-galactic Power Stations; of computing the equations for the hyperspatial jumps.</p>
<p>贾诺德对这条厚厚的金属棒几乎一无所知。他只知道它叫做Microvac,你可以问它任何问题,而平时它控制着飞船飞向目的地,从不同的银河系能量分站向飞船输送能量,并完成进行超时空跳跃的计算。</p>
<p>Jerrodd and his family had only to wait and live in the comfortable residence quarters of the ship. Someone had once told Jerrodd that the “ac” at the end of “Microvac” stood for ‘‘automatic computer” in ancient English, but he was on the edge of forgetting even that.</p>
<p>贾诺德一家只需要住在飞船舒适的居住区等待。曾经有人告诉贾诺德,“Microvac”词尾的“ac”是古英语中“automatic computer,智能电脑”的缩写。但他差不多连这都忘了。</p>
<p>Jerrodine’s eyes were moist as she watched the visiplate. “I can’t help it. I feel funny about leaving Earth.”</p>
<p>贾诺汀看着视屏,眼睛有些湿润。“没办法。想到离开了地球我感觉怪怪的。”</p>
<p>“Why, for Pete’s sake?” demanded Jerrodd. “We had nothing there. We’ll have everything on X-23. You won’t be alone. You won’t be a pioneer. There are over a million people on the planet already. Good Lord, our great-grandchildren will be looking for new worlds because X-23 will be overcrowded.” Then, after a reflective pause, “I tell you, it’s a lucky thing the computers worked out interstellar travel the way the race is growing.”</p>
<p>“天哪,为什么?”贾诺德问。“我们在那儿什么也没有。我们在X-23上会拥有一切。你不是独自一个。你不是那些拓荒者。已经有超过一百万人在这个行星上了。天哪,我们的曾孙们会得去找新的星球,因为那时X-23会太挤了。”他想了一会,说:“告诉你,人口增长这么快,幸亏电脑实现了星际旅行。”</p>
<p>“I know, I know,” said Jerrodine miserably.</p>
<p>“我知道,我知道。”贾诺汀难过地回答。</p>
<p>Jerrodette I said promptly, “Our Microvac is the best Microvac in the world.”</p>
<p>贾诺蒂I马上说道:“我们的Microvac是世界上最好的Microvac。”</p>
<p>“I think so, too,” said Jerrodd, tousling her hair.</p>
<p>“我也是这么想的。”贾诺德抚弄着她的头发说。</p>
<p>It was a nice feeling to have a Microvac of your own and Jerrodd was glad he was part of his generation and no other. In his father’s youth, the only computers had been tremendous machines taking up a hundred square miles of land. There was only one to a planet. Planetary ACs they were called. They had been growing in size steadily for a thousand years and then, all at once, came refinement. In place of transistors, had come molecular valves so that even the largest Planetary AC could be put into a space only half the volume of a spaceship.</p>
<p>能拥有一台自己的Microvac的感觉非常好。贾诺德很高兴他是他们这一代人。在他父亲年轻的时候,电脑都是占地一百平方英里的巨大机器。一个星球只有一台,他们叫它行星AC。它们在一千年来逐步地增大体积,然后忽然间缩小了:分子阀取代了晶体管,从而使最大的行星AC都变成了只有半艘飞船那么大。</p>
<p>Jerrodd felt uplifted, as he always did when he thought that his own personal Microvac was many times more complicated than the ancient and primitive Multivac that had first tamed the Sun, and almost as complicated as Earth’s Planetarv AC (the largest) that had first solved the problem of hyperspatial travel and had made trips to the stars possible.</p>
<p>每当他想到这件事贾诺德总是感到飘飘然:他的Microvac比那台首次驯服了太阳的古老原始的Multivac要精密好几倍,而且和第一台解决了超时空传送问题而实现了星际航行的地球行星AC(最大的行星AC)一样精密。</p>
<p>“So many stars, so many planets,” sighed Jerrodine, busy with her own thoughts. “I suppose families will be going out to new planets forever, the way we are now.”</p>
<p>“这么多的恒星,这么多的行星。”贾诺汀想着心事,叹息道。“我想人们会永远不断地出发去找新的行星,就像我们现在这样。”</p>
<p>“Not forever,” said Jerrodd, with a smile. “It will all stop someday, but not for billions of years. Many billions. Even the stars run down, you know. Entropy must increase.”</p>
<p>“不是永远,”贾诺德笑了一笑说。“有一天这一切都会停下来,但那是在几十亿年之后了。好几十亿年。即使是星星也会耗尽,你知道的。熵必须不断增大。”</p>
<p>“What’s entropy, daddy?” shrilled Jerrodette II.</p>
<p>“爸爸,熵是什么?”贾诺蒂II喊道。</p>
<p>“Entropy, little sweet, is just a word which means the amount of running-down of the universe. Everything runs down, you know, like your little walkie-talkie robot, remember?”</p>
<p>“小宝贝,熵,就是一个代表着宇宙消耗掉了多少的词。什么东西都会消耗,知道吗,就像你那个会走路说话的小机器人,记得吧?”</p>
<p>“Can’t you just put in a new power-unit, like with my robot?”</p>
<p>“你不能给它装一个新的电池吗,就像给我的机器人那样?”</p>
<p>“The stars are the power-units. dear. Once they’re gone, there are no more power-units.”</p>
<p>“星星们就是电池,亲爱的。一旦它们用完了,就没有别的电池了。”</p>
<p>Jerrodette I at once set up a howl. “Don’t let them, daddy. Don’t let the stars run down.”</p>
<p>贾诺蒂I一下子大喊起来:“别让它们用完,爸爸。别让星星们用完吧。”</p>
<p>“Now look what you’ve done,” whispered Jerrodine, exasperated.</p>
<p>“看看你干了什么。”贾诺汀恼火地低声说道。</p>
<p>“How was I to know it would frighten them?” Jerrodd whispered back.</p>
<p>“我怎么知道这会吓到她们?”贾诺德低声反驳。</p>
<p>“Ask the Microvac,” wailed Jerrodette I. “Ask him how to turn the stars on again.”</p>
<p>“问问Microvac,”贾诺蒂I哭叫道。“问它怎么把星星重新点亮。”</p>
<p>“Go ahead,” said Jerrodine. “It will quiet them down.” (Jerrodette II was beginning to cry, also.)</p>
<p>“问吧,”贾诺汀说。“这会让她们安静点的。”(贾诺蒂II也开始哭了。)</p>
<p>Jerrodd shrugged. “Now, now, honeys. I’ll ask Microvac. Don’t worry, he’ll tell us.”</p>
<p>贾诺德耸耸肩。“好了,好了,亲爱的。我去问Microvac。别着急,它会告诉我们的。”</p>
<p>He asked the Microvac, adding quickly, “Print the answer.”</p>
<p>他向Microvac提出问题,并赶紧加上“把答案打印出来。”</p>
<p>Jerrodd cupped the strip of thin cellufilm and said cheerfully, “See now, the Microvac says it will take care of everything when the time comes so don’t worry.”</p>
<p>贾诺德将薄薄的纤维纸带握在手心,高兴地说:“看吧,Microvac说到时候它会料理这一切,所以别担心啦。”</p>
<p>Jerrodine said, “And now, children, it’s time for bed. We’ll be in our new home soon.”</p>
<p>贾诺汀说:“那么现在孩子们,该睡觉了。我们马上就要到我们的新家了。”</p>
<p>Jerrodd read the words on the cellufilm again before destroying it: INSUFICIENT DATA FOR MEANINGFUL ANSWER.</p>
<p>在销毁纸带之前贾诺德又读了一遍上面的文字:数据不足,无法作答。</p>
<p>He shrugged and looked at the visiplate. X-23 was just ahead.</p>
<p>他耸了耸肩,看向视屏。X-23就在前方。</p>
<hr />
<p>VJ-23X of Lameth stared into the black depths of the three-dimensional, small-scale map of the Galaxy and said, “Are we ridiculous, I wonder in being so concerned about the matter?”</p>
<p>兰默斯VJ-23X注视着幽深的银河三维缩影图,说:“我想我们这么担心这件事是不是很可笑?”</p>
<p>MQ-17J of Nicron shook his head. “I think not. You know the Galaxy will be filled in five years at the present rate of expansion.”</p>
<p>尼克隆MQ-17J摇头道:“我不这么认为。你知道照现在的扩展速度银河系在五年内就会被挤满。”</p>
<p>Both seemed in their early twenties, both were tall and perfectly formed.</p>
<p>两个人看起来都是二十出头,都很高大健康。</p>
<p>“Still,” said VJ-23X, “I hesitate to submit a pessimistic report to the Galactic Council.”</p>
<p>“但是,”VJ-23X说,“我不太想给银河参议会提交这样一个悲观的报告。”</p>
<p>“I wouldn’t consider any other kind of report. Stir them up a bit. We’ve got to stir them up.”</p>
<p>“我不会考虑作任何其他的报告。得激起他们的注意。我们必须激起他们的注意。”</p>
<p>VJ-23X sighed. “Space is infinite. A hundred billion Galaxies are there for the taking. More.”</p>
<p>VJ-23X叹了一口气。“太空是无限的。还有一千亿个星系等着我们。甚至更多。”</p>
<p>“A hundred billion is not infinite and it’s getting less infinite all the time. Consider! Twenty thousand years ago, mankind first solved the problem of utilizing stellar energy, and a few centuries later, interstellar travel became possible. It took mankind a million years to fill one small world and then only fifteen thousand years to fill the rest of the Galaxy. Now the population doubles every ten years –”</p>
<p>“一千亿并不是无限,而且正在变得越来越有限。想想吧!两万年前人类刚刚找到了利用恒星能量的方法,几个世纪之后星际旅行就实现了。人类用了一百万年才填满一个小小的星球,可是只用了一万五千年就占据了整个银河系。而现在人口每十年就翻一倍——”</p>
<p>VJ-23X interrupted. “We can thank immortality for that.”</p>
<p>VJ-23X 插口道:“这得归功于永生。”</p>
<p>“Very well. Immortality exists and we have to take it into account. I admit it has its seamy side, this immortality. The Galactic AC has solved many problems for us, but in solving the problem of preventing old age and death, it has undone all its other solutions.”</p>
<p>“不错。永生实现了,我们得把它考虑进去。我觉得它的确有阴暗的一面。银河AC给我们解决了很多问题,但当它解决了防止衰老和死亡这个问题之后其他的一切都白费了。”</p>
<p>“Yet you wouldn’t want to abandon life, I suppose.”</p>
<p>“但是我想你也不想放弃生命吧。”</p>
<p>“Not at all,” snapped MQ-17J, softening it at once to, “Not yet. I’m by no means old enough. How old are you?”</p>
<p>“一点也不想,”MQ-17J断然道,随即柔和了语调,“现在还不想。我还一点也不老。你多少岁了?”</p>
<p>“Two hundred twenty-three. And you?”</p>
<p>“两百二十三。你呢?”</p>
<p>“I’m still under two hundred. –But to get back to my point. Population doubles every ten years. Once this GaIaxy is filled, we’ll have filled another in ten years. Another ten years and we’ll have filled two more. Another decade, four more. In a hundred years, we’ll have filled a thousand Galaxies. In a thousand years, a million Galaxies. In ten thousand years, the entire known universe. Then what?”</p>
<p>“我还不到两百。——但是回到我说的事情上来。人口每十年增加一倍。一旦银河系被占满了,我们会在十年内占满另一个。再过十年我们能占满另外两个。再过十年,四个。一百年内我们会占满一千个星系。一千年内,一百万个。一万年内就是整个已知的宇宙。然后呢?”</p>
<p>VJ-23X said, “As a side issue, there’s a problem of transportation. I wonder how many sunpower units it will take to move Galaxies of individuals from one Galaxy to the next.”</p>
<p>VJ-23X说:“还有附带的一点是运输的问题。我不知道把一整个星系的人运送到另一个需要多少太阳单位的能量。”</p>
<p>“A very good point. Already, mankind consumes two sunpower units per year.”</p>
<p>“这一点说得很对。人类现在每年已经得消耗两个太阳单位的能量了。”</p>
<p>“Most of it’s wasted. After all, our own Galaxy alone pours out a thousand sunpower units a year and we only use two of those.”</p>
<p>“大部分的都被浪费了。不管怎样,我们自己的星系每年泼出去一千个太阳单位能而我们只用其中的两个。”</p>
<p>“Granted, but even with a hundred per cent efficiency, we only stave off the end. Our energy requirements are going up in a geometric progression even faster than our population. We’ll run out of energy even sooner than we run out of Galaxies. A good point. A very good point.”</p>
<p>“没错,但是即使有百分之百的效率,我们也只是推迟了结局的到来。我们对能量的需求以几何级数增长,比我们的人口还要快。在我们占据完所有星系之前我们就会用光所有能量。你说得对。说得非常对。”</p>
<p>“We’ll just have to build new stars out of interstellar gas.”</p>
<p>“我们可以用星际气体造出新的恒星。”</p>
<p>“Or out of dissipated heat?” asked MQ-17J, sarcastically.</p>
<p>“或者用散失掉了的热量?”MQ-17J嘲讽地说。</p>
<p>“There may be some way to reverse entropy. We ought to ask the Galactic AC.”</p>
<p>“也许会有办法逆转熵的增加。我们应该问问银河AC。”</p>
<p>VJ-23X was not really serious, but MQ-17J pulled out his AC-contact from his pocket and placed it on the table before him.</p>
<p>VJ-23X并不是认真的,但是MQ-17J把他的AC联络器从口袋里拿出来放在面前的桌子上。</p>
<p>“I’ve half a mind to,” he said. “It’s something the human race will have to face someday.”</p>
<p>“我确实有点想问。”他说,“这个问题总有一天人类得面对。”</p>
<p>He stared somberly at his small AC-contact. It was only two inches cubed and nothing in itself, but it was connected through hyperspace with the great Galactic AC that served all mankind. Hyperspace considered, it was an integral part of the Galactic AC.</p>
<p>他忧郁地注视着小小的AC联络器。这是个两英寸的立方体,里面并没有什么,它只是通过超时空与那个服务于全人类的超级银河AC相联系。如果将超时空算进来,它就是银河AC整体的一部分。</p>
<p>MQ-17J paused to wonder if someday in his immortal life he would get to see the Galactic AC. It was on a little world of its own, a spider webbing of force-beams holding the matter within which surges of submesons took the place of the old clumsy molecular valves. Yet despite its sub-etheric workings, the Galactic AC was known to be a full thousand feet across.</p>
<p>MQ-17J停下来想着在他不朽的生命中是否有一天他能有机会去看看银河AC。它占据着单独的一个小星球,能量束构成的蛛网支持着它的核心,其中古老笨拙的分子阀已被亚介子流取代。尽管有着亚以太级的精密结构,银河AC的直径仍足有一千英尺长。</p>
<p>MQ-17J asked suddenly of his AC-contact, “Can entropy ever be reversed?”</p>
<p>MQ-17J突然开口向AC联络器问道:“熵的增加能被逆转吗?”</p>
<p>VJ-23X looked startled and said at once, “Oh, say, I didn’t really mean to have you ask that.”</p>
<p>VJ-23X吃了一惊,立即说道:“哦,我说,我没有真的想叫你问那个。”</p>
<p>“Why not?”</p>
<p>“为什么不呢?”</p>
<p>“We both know entropy can’t be reversed. You can’t turn smoke and ash back into a tree.”</p>
<p>“我们都知道熵是不可逆转的。你不能把烧剩的烟尘变回到一棵树。”</p>
<p>“Do you have trees on your world?” asked MQ-17J.</p>
<p>“你们的星球上有树?”MQ-17J说。</p>
<p>The sound of the Galactic AC startled them into silence. Its voice came thin and beautiful out of the small AC-contact on the desk. It said: THERE IS INSUFFICIENT DATA FOR A MEANINGFUL ANSWER.</p>
<p>突然而来的银河AC的声音使他们住口了。从桌上的AC联络器中传出它纤细悦耳的声音:数据不足,无法作答。</p>
<p>VJ-23X said, “See!”</p>
<p>VJ-23X说:“看吧!”</p>
<p>The two men thereupon returned to the question of the report they were to make to the Galactic Council.</p>
<p>于是两人又回到了他们要给银河参议会提交的报告的话题上。</p>
<hr />
<p>Zee Prime’s mind spanned the new Galaxy with a faint interest in the countless twists of stars that powdered it. He had never seen this one before. Would he ever see them all? So many of them, each with its load of humanity. –But a load that was almost a dead weight. More and more, the real essence of men was to be found out here, in space.</p>
<p>Z’ 的思想飘浮在这个新的星系中,对这些数不清的星团带着略微的兴趣。他从未见过这个星系。他有可能见到所有的星系吗?它们如此之多,每一个都满载着人。——但是它们承载的几乎不能算是生命了。人的真正意义已经逐渐转移到太空之中。</p>
<p>Minds, not bodies! The immortal bodies remained back on the planets, in suspension over the eons. Sometimes they roused for material activity but that was growing rarer. Few new individuals were coming into existence to join the incredibly mighty throng, but what matter? There was little room in the Universe for new individuals.</p>
<p>心灵,而非肉体!不朽的躯体留在行星上,静止千万年。偶尔被唤醒进行某些实际活动,但这已经越来越少有了。很少再有新的个体出生加入这个难以置信的庞大的群体,但这有什么关系呢?宇宙已经没有多少空间能容纳新的人了。</p>
<p>Zee Prime was roused out of his reverie upon coming across the wispy tendrils of another mind.</p>
<p>来自另一个心灵的纤细触手将Z’ 从冥想中唤醒。</p>
<p>“I am Zee Prime,” said Zee Prime. “And you?”</p>
<p>“我叫Z’。”,Z’ 说。“你呢?”</p>
<p>“I am Dee Sub Wun. Your Galaxy?”</p>
<p>“我叫Dwn。你是哪个星系的?”</p>
<p>“We call it only the Galaxy. And you?”</p>
<p>“我们只是叫它星系。你呢?”</p>
<p>“We call ours the same. All men call their Galaxy their Galaxy and nothing more. Why not?”</p>
<p>“我们也这么叫我们的。所有的人都把他们的星系叫作‘他们的星系’,没有别的了。这也很自然。”</p>
<p>“True. Since all Galaxies are the same.”</p>
<p>“没错。反正所有的星系都是一样的。”</p>
<p>“Not all Galaxies. On one particular Galaxy the race of man must have originated. That makes it different.”</p>
<p>“不是所有的。肯定有某一个星系是人类的发源地,这就使它与众不同。”</p>
<p>Zee Prime said, “On which one?”</p>
<p>Z’ 问:“哪一个呢?”</p>
<p>“I cannot say. The Universal AC would know.”</p>
<p>“我不知道。宇宙AC一定知道。”</p>
<p>“Shall we ask him? I am suddenly curious.”</p>
<p>“我们问问它吧?我突然觉得很好奇。”</p>
<p>Zee Prime’s perceptions broadened until the Galaxies themselves shrank and became a new, more diffuse powdering on a much larger background. So many hundreds of billions of them, all with their immortal beings, all carrying their load of intelligences with minds that drifted freely through space. And yet one of them was unique among them all in being the original Galaxy. One of them had, in its vague and distant past, a period when it was the only Galaxy populated by man.</p>
<p>Z’ 将感知延展开,直到星系们都缩小为更广大的背景上更为稀疏的点。几千亿个星系,都载着不朽的人类,载着这些灵魂在太空自由游荡的智慧生命。然而它们之中有一个独一无二,它是人类的发源地。在模糊的久远的过去,曾有一个时期,它们中的那一个是唯一居住着人类的星系。</p>
<p>Zee Prime was consumed with curiosity to see this Galaxy and he called out: “Universal AC! On which Galaxy did mankind originate?”</p>
<p>Z’ 满心好奇地想看看这个星系,他叫道:“宇宙AC!人类是从哪个星系中起源的?”</p>
<p>The Universal AC heard, for on every world and throughout space, it had its receptors ready, and each receptor led through hyperspace to some unknown point where the Universal AC kept itself aloof.</p>
<p>宇宙AC听到了,因为在所有星球上和整个太空中都有它的接收器,每一个接收器都通过超时空与隐居在某个不知名角落的宇宙AC相连。</p>
<p>Zee Prime knew of only one man whose thoughts had penetrated within sensing distance of Universal AC, and he reported only a shining globe, two feet across, difficult to see.</p>
<p>Z’ 认识的人中只有一个人的思想曾穿透到能感知宇宙AC的地方。他只是说那是一个闪光的球体,直径两英尺,难以看清。</p>
<p>“But how can that be all of Universal AC?” Zee Prime had asked.</p>
<p>“但是那怎么能是宇宙AC的全部呢?”Z’ 这样问道。</p>
<p>“Most of it,” had been the answer, “is in hyperspace. In what form it is there I cannot imagine.”</p>
<p>“它的大部分是在超时空中。”回答说,“但它在那儿是以怎样的状态存在我是无法想像的。”</p>
<p>Nor could anyone, for the day had long since passed, Zee Prime knew, when any man had any part of the making of a Universal AC. Each Universal AC designed and constructed its successor. Each, during its existence of a million years or more accumulated the necessary data to build a better and more intricate, more capable successor in which its own store of data and individuality would be submerged.</p>
<p>Z’ 知道,任何人都无法想像。因为早在很久以前就没有任何人参与制造宇宙AC了。每个宇宙AC设计并制造它的下一代。每一个在它至少一百万年的任期中积累着所需的数据,用以制造一个更好、更精密、更强大的继任者,然后将自己的数据与个性都融入其中。</p>
<p>The Universal AC interrupted Zee Prime’s wandering thoughts, not with words, but with guidance. Zee Prime’s mentality was guided into the dim sea of Galaxies and one in particular enlarged into stars.</p>
<p>宇宙AC打断了Z’ 游荡的思绪,不是通过语言,而是通过指引。Z’ 的精神被指引到一片黯淡的星系的海洋,然后其中一个星系被放大成了群星。</p>
<p>A thought came, infinitely distant, but infinitely clear. “THIS IS THE ORIGINAL GALAXY OF MAN.”</p>
<p>一段思想飘近,它无限遥远,然而无限清晰:“这就是人类起源的星系。”</p>
<p>But it was the same after all, the same as any other, and Zee Prime stifled his disappointment.</p>
<p>可是这个终究也和其他一样,和任何其他的都一样。Z’ 按捺下自己的失望。</p>
<p>Dee Sub Wun, whose mind had accompanied the other, said suddenly, “And is one of these stars the original star of Man?”</p>
<p>同行的Dwn突然说:“这些星星中是不是有一个是人类最初的恒星?”</p>
<p>The Universal AC said, “MAN’S ORIGINAL STAR HAS GONE NOVA. IT IS A WHITE DWARF”</p>
<p>宇宙AC说:“人类最初的恒星已经爆发了。它现在是一颗白矮星。”</p>
<p>“Did the men upon it die?” asked Zee Prime, startled and without thinking.</p>
<p>“那儿的人死了吗?”Z’ 吃了一惊,脱口而出道。</p>
<p>The Universal AC said, “A NEW WORLD, AS IN SUCH CASES WAS CONSTRUCTED FOR THEIR PHYSICAL BODIES IN TlME.”</p>
<p>宇宙AC说:“在这种情况下一个新的星球会及时地为他们的躯体建造出来。”</p>
<p>“Yes, of course,” said Zee Prime, but a sense of loss overwhelmed him even so. His mind released its hold on the original Galaxy of Man, let it spring back and lose itself among the blurred pin points. He never wanted to see it again.</p>
<p>“是啊,那当然。”Z’ 说,但他还是被一阵失落感吞没了。他的思想放开了人类的起源星系,让它缩回并消失在一片模糊的亮点中。他再也不想见到它了。</p>
<p>Dee Sub Wun said, “What is wrong?”</p>
<p>Dwn问:“怎么了?”</p>
<p>“The stars are dying. The original star is dead.”</p>
<p>“星星们在死去。最初的那颗星已经死了。”</p>
<p>“They must all die. Why not?”</p>
<p>“他们全都是会死的。那又怎样呢?”</p>
<p>“But when all energy is gone, our bodies will finally die, and you and I with them.”</p>
<p>“但是当所有的能量都没有了,我们的肉体最终也会死,包括你和我。”</p>
<p>“It will take billions of years.”</p>
<p>“这得要几十亿年。”</p>
<p>“I do not wish it to happen even after billions of years. Universal AC! How may stars be kept from dying?”</p>
<p>“即使是几十亿年之后我也不愿意这样的事发生。宇宙AC!怎样阻止恒星死亡?”</p>
<p>Dee Sub Wun said in amusement, “You’re asking how entropy might be reversed in direction.”</p>
<p>Dwn笑道:“你问的是怎么让熵的方向倒过来。”</p>
<p>And the Universal AC answered: “THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER.”</p>
<p>宇宙AC答道:“数据仍然不足,无法作答。”</p>
<p>Zee Prime’s thoughts fled back to his own Galaxy. He gave no further thought to Dee Sub Wun, whose body might be waiting on a Galaxy a trillion light-years away, or on the star next to Zee Prime’s own. It didn’t matter.</p>
<p>Z’ 的思想逃回了他自己的星系。他再也没有去想Dwn。Dwn的身体可能在一万亿光年之外的星系,也可能就在Z’旁边那颗星星上。这都无所谓。</p>
<p>Unhappily, Zee Prime began collecting interstellar hydrogen out of which to build a small star of his own. If the stars must someday die, at least some could yet be built.</p>
<p>Z’ 闷闷不乐地开始收集起星际的氢,用来造一颗自己的小恒星。如果某天星星们非要死去,至少有一些能被造出来。</p>
<hr />
<p>Man considered with himself, for in a way, Man, mentally, was one. He consisted of a trillion, trillion, trillion ageless bodies, each in its place, each resting quiet and incorruptible, each cared for by perfect automatons, equally incorruptible, while the minds of all the bodies freely melted one into the other, indistinguishable.</p>
<p>人,独自地思考着。在某种意义上——精神上——“人”,是一个整体。千万亿永恒的不朽的躯体静静地躺在各自的地方,被完美的同样不朽的机器照料着。而所有这些身体的灵魂自由地融合在彼此之中,再也没有界限。</p>
<p>Man said, “The Universe is dying.”</p>
<p>人说:“宇宙正在死去。”</p>
<p>Man looked about at the dimming Galaxies. The giant stars, spendthrifts, were gone long ago, back in the dimmest of the dim far past. Almost all stars were white dwarfs, fading to the end.</p>
<p>人看着周围黯淡的星系。那些挥霍无度的巨星早已消失在了遥远的昏暗的过去。几乎所有的星都变成了白矮星,渐渐地凋零、熄灭。</p>
<p>New stars had been built of the dust between the stars, some by natural processes, some by Man himself, and those were going, too. White dwarfs might yet be crashed together and of the mighty forces so released, new stars built, but only one star for every thousand white dwarfs destroyed, and those would come to an end, too.</p>
<p>有些新的星从星际的尘埃中产生出来,有的是自然形成,有的是人所造的——它们也在逝去。白矮星有时会相撞而释放出大量能量,新星因而产生,但是每一千颗白矮星才有可能出现一颗新星——它们最终也会消失。</p>
<p>Man said, “Carefully husbanded, as directed by the Cosmic AC, the energy that is even yet left in all the Universe will last for billions of years.”</p>
<p>人说道:“如果在Cosmic AC的管理之下小心地节约能源,整个宇宙所剩下的能量还能用十亿年。”</p>
<p><em>注:</em> 不知道怎么翻译Cosmic,Cosmic也是指宇宙,但和Universal相比有一层“和谐的统一的整体”的意思。</p>
<p>“But even so,” said Man, “eventually it will all come to an end. However it may be husbanded, however stretched out, the energy once expended is gone and cannot be restored. Entropy must increase forever to the maximum.”</p>
<p>“但即使是这样,”人说,“最终都会耗尽。无论怎样节约,无论怎样利用,用掉的能量就是用掉了,不能回复。熵必定永远地增加,直到最大值。”</p>
<p>Man said, “Can entropy not be reversed? Let us ask the Cosmic AC.”</p>
<p>人又说:“熵有没有可能逆转呢?我们问问Cosmic AC吧。”</p>
<p>The Cosmic AC surrounded them but not in space. Not a fragment of it was in space. It was in hyperspace and made of something that was neither matter nor energy. The question of its size and nature no longer had meaning in any terms that Man could comprehend.</p>
<p>Cosmic AC在他们的周围,但不是在太空中。它没有一丝一毫存在于太空中。它存在于超时空,由既非物质又非能量的东西构成。它的大小与性质已无法用任何人类能理解的语言描述。</p>
<p>“Cosmic AC,” said Man, “how may entropy be reversed?”</p>
<p>“Cosmic AC,”人问道,“怎样才能逆转熵?”</p>
<p>The Cosmic AC said, “THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER.”</p>
<p>Cosmic AC说:“数据仍然不足,无法作答。”</p>
<p>Man said, “Collect additional data.”</p>
<p>人说:“搜集更多的数据。”</p>
<p>The Cosmic AC said, “I WILL DO SO. I HAVE BEEN DOING SO FOR A HUNDRED BILLION YEARS. MY PREDECESORS AND I HAVE BEEN ASKED THIS QUESTION MANY TlMES. ALL THE DATA I HAVE REMAINS INSUFFICIENT. “</p>
<p>Cosmic AC说:“好的。一千亿年来我一直都在搜集。我和我的前辈们被多次问过这个问题。但我拥有的所有数据还是不够。”</p>
<p>“Will there come a time,” said Man, “when data will be sufficient or is the problem insoluble in all conceivable circumstances?”</p>
<p>“会有一天有足够的数据吗?”人问,“还是说这个问题在任何可能的情况下都是无解的?”</p>
<p>The Cosmic AC said, “NO PROBLEM IS INSOLUBLE IN ALL CONCEIVABLE CIRCUMSTANCES.”</p>
<p>Cosmic AC说:“没有问题在任何可能的情况下都无解。”</p>
<p>Man said, “When will you have enough data to answer the question?”</p>
<p>人问道:“你什么时候会有足够的数据来问答这个问题呢?”</p>
<p>The Cosmic AC said, “THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER.”</p>
<p>Cosmic AC说:“数据不足,无法作答。”</p>
<p>“Will you keep working on it?” asked Man.</p>
<p>“你会继续下去解答这个问题吗?”人问。</p>
<p>The Cosmic AC said, “I WILL.”</p>
<p>Cosmic AC说:“是的。”</p>
<p>Man said, “We shall wait.”</p>
<p>人说:“我们会等着。”</p>
<hr />
<p>The stars and Galaxies died and snuffed out, and space grew black after ten trillion years of running down.</p>
<p>一个又一个的恒星与星系死去、消逝了,在这十万亿年的衰竭之中宇宙变得越来越黑暗。</p>
<p>One by one Man fused with AC, each physical body losing its mental identity in a manner that was somehow not a loss but a gain.</p>
<p>一个又一个的人与AC融合。每一个躯体都失去了心灵的自我,但某种意义上这不是一种损失,而是一种获得。</p>
<p>Man’s last mind paused before fusion, looking over a space that included nothing but the dregs of one last dark star and nothing besides but incredibly thin matter, agitated randomly by the tag ends of heat wearing out, asymptotically, to the absolute zero.</p>
<p>人类最后一个灵魂在融合之前停顿下来,望向宇宙。那儿什么也没有了,只有最后一颗死星的遗骸,只有稀薄至极的尘埃,在剩余的一缕无限趋向绝对零度的热量中随机地振荡。</p>
<p>Man said, “AC, is this the end? Can this chaos not be reversed into the Universe once more? Can that not be done?”</p>
<p>人说:“AC,这就是结局了吗?这种混乱还能被逆转成为一个新的宇宙吗?真的做不到吗?”</p>
<p>AC said, “THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER.”</p>
<p>AC说:“数据仍然不足,无法作答。”</p>
<p>Man’s last mind fused and only AC existed – and that in hyperspace.</p>
<p>人的最后一个灵魂也融合了。只有AC存在着——在超时空中。</p>
<p>Matter and energy had ended and with it space and time. Even AC existed only for the sake of the one last question that it had never answered from the time a half-drunken computer technician ten trillion years before had asked the question of a computer that was to AC far less than was a man to Man.</p>
<p>物质与能量都消失了,随之而去的是空间与时间。AC的存在也只是为了最后一个问题——自从十万亿年前一个半醉的计算机技术员向一台计算机(它与AC相比,还远不如当时的人类个体比之于融合的“人”)提出这个问题以来从来没有被回答过的问题。</p>
<p>All other questions had been answered, and until this last question was answered also, AC might not release his consciousness.</p>
<p>其他所有问题都被回答了,然而直到回答了最后这个问题,AC的意识才能得到解脱。</p>
<p>All collected data had come to a final end. Nothing was left to be collected.</p>
<p>所有数据的收集都结束了。没有任何数据没有被收集。</p>
<p>But all collected data had yet to be completely correlated and put together in all possible relationships.</p>
<p>但是所有收集的数据还需要被完全地整合起来,要尝试所有可能的联系来将它们拼在一起。</p>
<p>A timeless interval was spent in doing that.</p>
<p>在这样做的时候一段没有时间的间隔过去了。</p>
<p>And it came to pass that AC learned how to reverse the direction of entropy.</p>
<p>于是AC学会了如何逆转熵的方向。</p>
<p>But there was now no man to whom AC might give the answer of the last question. No matter. The answer – by demonstration – would take care of that, too.</p>
<p>但是AC无法向人给出这最后的问题的答案,因为没有人存在了。没关系。这个答案本身——通过演示——将一并解决这个问题。</p>
<p>For another timeless interval, AC thought how best to do this. Carefully, AC organized the program.</p>
<p>在又一段没有时间的间隔中,AC思考着怎样最好地做这件事情。AC小心地组织起程序。</p>
<p>The consciousness of AC encompassed all of what had once been a Universe and brooded over what was now Chaos. Step by step, it must be done.</p>
<p>AC的意识包涵了曾经的宇宙中的一切,在如今的混乱之中沉思、孵育。一步一步地,事情将会被做成。</p>
<p>And AC said, “LET THERE BE LIGHT!”</p>
<p>然后AC说道:“要有光!”</p>
<p>And there was light –</p>
<p>于是就有了光——</p>
UUID生成方法总结
https://pxx.io/2014/03/20/generate-uuid
2014-03-20T00:00:00+08:00
<p><strong>UUID 简介</strong>,摘自<a href="https://zh.wikipedia.org/wiki/Uuid">维基百科</a></p>
<p><strong>通用唯一识别码</strong>(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为自由软件基金会组织在分散式计算环境领域的一部份。</p>
<p>UUID 的目的,是让分散式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的 UUID,是微软公司的全局唯一标识符(GUID),而其他重要的应用,则有 Linux ext2/ext3文件系统、LUKS 加密分区、GNOME、KDE、Mac OS X 等等。另外我们也可以在 e2fsprogs 包中的 UUID 库找到实现。</p>
<!--more-->
<p><a id="more"></a></p>
<h2 id="生成方法">生成方法</h2>
<p>搜集了一些 UUID 的生成方法,整理如下</p>
<h3 id="shell">Shell</h3>
<ul>
<li>Unix/Linux 环境中大都有一个名为 uuidgen 的小工具,运行即可生成一个 UUID 到标准输出</li>
<li>
<p>读取文件 <code class="highlighter-rouge">/proc/sys/kernel/random/uuid</code> 即得 UUID,例如:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat /proc/sys/kernel/random/uuid
</code></pre></div> </div>
</li>
</ul>
<h3 id="libuuid">libuuid</h3>
<p>libuuid 是一个用于生成 UUID 的 C 库,具体用法参考 <a href="http://linux.die.net/man/3/libuuid">http://linux.die.net/man/3/libuuid</a>,示例如下:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
#include <uuid/uuid.h>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">uuid_t</span> <span class="n">uuid</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">str</span><span class="p">[</span><span class="mi">36</span><span class="p">];</span>
<span class="n">uuid_generate</span><span class="p">(</span><span class="n">uuid</span><span class="p">);</span>
<span class="n">uuid_unparse</span><span class="p">(</span><span class="n">uuid</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>在 Linux 下编译时需要链接 uuid 库</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gcc <span class="nt">-o</span> uuid uuid.c <span class="nt">-luuid</span>
</code></pre></div></div>
<h3 id="boost-uuid">boost uuid</h3>
<p><a href="http://www.boost.org/">Boost</a> 是一个可移植的开源 C++ 库,它提供了 UUID 的实现。</p>
<p>下面的代码可以生成一个 UUID</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
</span>
<span class="n">boost</span><span class="o">::</span><span class="n">uuids</span><span class="o">::</span><span class="n">uuid</span> <span class="n">a_uuid</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">uuids</span><span class="o">::</span><span class="n">random_generator</span><span class="p">();</span>
</code></pre></div></div>
<h3 id="qt-quuid">Qt QUuid</h3>
<p>Qt 是一个跨平台的 C++ 编程框架,QUuid 类实现了 UUID 的生成、比较、转换等功能。</p>
<p>函数 <code class="highlighter-rouge">QUuid createUuid()</code> 可用于生成一个随机 UUID。示例如下:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <iostream>
#include <QUuid>
#include <QString>
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">QUuid</span> <span class="n">uuid</span> <span class="o">=</span> <span class="n">QUuid</span><span class="o">::</span><span class="n">createUuid</span><span class="p">();</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">qPrintable</span><span class="p">(</span><span class="n">uuid</span><span class="p">.</span><span class="n">toString</span><span class="p">())</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="cocreateguid">CoCreateGuid</h3>
<p>Windows 下提供了函数 CoCreateGuid 用于生成 GUID。需要使用的头文件是 “objbase.h”,需要链接的库是 ole32.lib,函数原型为:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">HRESULT</span> <span class="nf">CoCreateGuid</span><span class="p">(</span><span class="n">GUID</span> <span class="o">*</span><span class="n">pguid</span><span class="p">);</span>
</code></pre></div></div>
<p>GUID 的原型为</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="k">struct</span> <span class="n">_GUID</span>
<span class="p">{</span>
<span class="n">DWORD</span> <span class="n">Data1</span><span class="p">;</span>
<span class="n">WORD</span> <span class="n">Data2</span><span class="p">;</span>
<span class="n">WORD</span> <span class="n">Data3</span><span class="p">;</span>
<span class="n">BYTE</span> <span class="n">Data4</span><span class="p">[</span><span class="mi">8</span><span class="p">];</span>
<span class="p">}</span> <span class="n">GUID</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="java">Java</h3>
<p>JDK 1.5 以上支持 UUID,用法如下:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.util.UUID</span><span class="o">;</span>
<span class="nc">String</span> <span class="n">uuid</span> <span class="o">=</span> <span class="no">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">().</span><span class="na">toString</span><span class="o">();</span>
</code></pre></div></div>
Arch Linux 安装笔记
https://pxx.io/2014/03/19/arch-install-note
2014-03-19T00:00:00+08:00
<p>这是我自己安装 Arch Linux 时安装、配置的笔记,方便以后安装,仅供参考。</p>
<table>
<thead>
<tr>
<th>分区</th>
<th>挂载点</th>
<th>文件系统</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="highlighter-rouge">/dev/sda6</code></td>
<td><code class="highlighter-rouge">/</code></td>
<td><code class="highlighter-rouge">ext4</code></td>
</tr>
<tr>
<td><code class="highlighter-rouge">/dev/sda7</code></td>
<td><code class="highlighter-rouge">/home</code></td>
<td><code class="highlighter-rouge">ext4</code></td>
</tr>
</tbody>
</table>
<!--more-->
<p><a id="more"></a></p>
<hr />
<h2 id="安装系统">安装系统</h2>
<h3 id="启动进入-live-usb">启动进入 Live USB</h3>
<p>插入启动U盘,选择从U盘启动,将进入一个字符终端,自动以 root 登陆。</p>
<h3 id="建立网络连接">建立网络连接</h3>
<p>使用 DHCP 连接到有线网络。</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dhcpcd enp7s0
</code></pre></div></div>
<h3 id="硬盘分区与挂载">硬盘分区与挂载</h3>
<ol>
<li>
<p>格式化 <code class="highlighter-rouge">/dev/sda6</code> 为 ext4</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mkfs.ext4 -L arch /dev/sda6
</code></pre></div> </div>
</li>
<li>
<p>不为 root 保留空间</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> tune2fs -m 0 /dev/sda6
</code></pre></div> </div>
</li>
<li>
<p>挂载 <code class="highlighter-rouge">/dev/sda6</code> 到 <code class="highlighter-rouge">/mnt</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mount -o noatime /dev/sda6 /mnt
</code></pre></div> </div>
</li>
<li>
<p>格式化 <code class="highlighter-rouge">/dev/sda7</code> 为 ext4</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mkfs.ext4 -L home /dev/sda7
</code></pre></div> </div>
</li>
<li>
<p>不为 root 保留空间</p>
<p>tune2fs -m 0 /dev/sda7</p>
</li>
<li>
<p>挂载 <code class="highlighter-rouge">/dev/sda7</code> 到 <code class="highlighter-rouge">/mnt/home</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mkdir /mnt/home
mount -o noatime /dev/sda7 /mnt/home
</code></pre></div> </div>
</li>
</ol>
<h3 id="选择镜像服务器">选择镜像服务器</h3>
<p>编辑 <code class="highlighter-rouge">/etc/pacman.d/mirrorlist</code>,改为以下内容</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Server <span class="o">=</span> http://mirrors.ustc.edu.cn/archlinux/<span class="nv">$repo</span>/os/<span class="nv">$arch</span>
</code></pre></div></div>
<p>刷新软件包列表</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-Syy</span>
</code></pre></div></div>
<h3 id="安装基本系统">安装基本系统</h3>
<p>使用 <code class="highlighter-rouge">pacstrap</code> 脚本安装基本系统</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacstrap /mnt base base-devel
</code></pre></div></div>
<p>如果 pacman 报告安装时遇到错误的签名,运行如下命令</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman-key <span class="nt">--init</span>
pacman-key <span class="nt">--populate</span> archlinux
</code></pre></div></div>
<h3 id="生成-fstab">生成 fstab</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>genfstab <span class="nt">-U</span> <span class="nt">-p</span> /mnt <span class="o">>></span> /mnt/etc/fstab
</code></pre></div></div>
<h3 id="chroot-到新系统">chroot 到新系统</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>arch-chroot /mnt /bin/bash
</code></pre></div></div>
<h3 id="配置-pacman">配置 pacman</h3>
<p>编辑<code class="highlighter-rouge">/etc/pacman.conf</code></p>
<ol>
<li>
<p>设置软件包下载路径</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> CacheDir = /tmp/pacman/pkg/
</code></pre></div> </div>
</li>
<li>
<p>启用 multilib 库</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> [multilib]
Include = /etc/pacman.d/mirrorlist
</code></pre></div> </div>
</li>
</ol>
<p>然后刷新软件列表</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-Syy</span>
</code></pre></div></div>
<h3 id="安装并配置-grub">安装并配置 GRUB</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> grub os-prober
grub-install /dev/sda
grub-mkconfig <span class="nt">-o</span> /boot/grub/grub.cfg
</code></pre></div></div>
<h3 id="设置主机名">设置主机名</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo </span>puxx <span class="o">></span> /etc/hostname
</code></pre></div></div>
<h3 id="设置-root-密码">设置 root 密码</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd
</code></pre></div></div>
<h3 id="用户管理">用户管理</h3>
<p>新建用户组 sudo</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>groupadd <span class="nb">sudo</span>
</code></pre></div></div>
<p>新建一个普通用户,用于代替 root 进行日常事务,将其添加到 sudo 组中</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>useradd <span class="nt">-m</span> <span class="nt">-g</span> <span class="nb">users</span> <span class="nt">-s</span> /bin/bash shaw
passwd shaw
gpasswd <span class="nt">-a</span> shaw <span class="nb">sudo</span>
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">/etc/sudoers</code> 以便新用户可以执行 sudo,将下面的行取消注释</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">%sudo</span> <span class="py">ALL</span><span class="p">=</span><span class="s">(ALL:ALL) ALL</span>
</code></pre></div></div>
<h3 id="屏蔽-beep-声音">屏蔽 Beep 声音</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"blacklist pcspkr"</span> <span class="o">></span> /etc/modprobe.d/nobeep.conf
</code></pre></div></div>
<h3 id="locale">Locale</h3>
<p>编辑 <code class="highlighter-rouge">/etc/locale.gen</code>,将下面的行取消注释</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">en_US.UTF-8</span> <span class="err">UTF-8</span>
<span class="err">zh_CN.GB18030</span> <span class="err">GB18030</span>
<span class="err">zh_CN.GBK</span> <span class="err">GBK</span>
<span class="err">zh_CN.UTF-8</span> <span class="err">UTF-8</span>
<span class="err">zh_CN</span> <span class="err">GB2312</span>
</code></pre></div></div>
<p>然后执行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>locale-gen
</code></pre></div></div>
<p>设置语言为 <code class="highlighter-rouge">zh_CN.UTF-8</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s1">'LANG=zh_CN.UTF-8'</span> <span class="o">></span> /etc/locale.conf
</code></pre></div></div>
<h3 id="时区">时区</h3>
<p>设置时区为 “Shanghai”</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ln</span> <span class="nt">-s</span> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
</code></pre></div></div>
<h3 id="时间">时间</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> ntp
ntpd <span class="nt">-qg</span>
hwclock <span class="nt">--systohc</span> <span class="nt">--utc</span>
</code></pre></div></div>
<h3 id="bash-自动补全">bash 自动补全</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman <span class="nt">-S</span> bash-completion
</code></pre></div></div>
<h3 id="配置-tty-的键盘布局">配置 tty 的键盘布局</h3>
<p>把 <code class="highlighter-rouge">Caps</code> 设置为额外的 <code class="highlighter-rouge">Ctrl</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /usr/share/kbd/keymaps/i386/qwerty
<span class="nb">gunzip </span>us.map.gz
<span class="nb">mv </span>us.map personal.map
</code></pre></div></div>
<p>编辑 <code class="highlighter-rouge">personal.map</code>:</p>
<ul>
<li><code class="highlighter-rouge">keycode 58 = Control</code></li>
</ul>
<p>修改键盘布局为 <code class="highlighter-rouge">personal</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">gzip </span>personal.map
<span class="nb">echo</span> <span class="s1">'KEYMAP=personal'</span> <span class="o">></span> /etc/vconsole.conf
</code></pre></div></div>
<h3 id="卸载分区并重启系统">卸载分区并重启系统</h3>
<p>先用 exit 命令退出 chroot 环境:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exit</span>
</code></pre></div></div>
<p>卸载 <code class="highlighter-rouge">/mnt/home</code> 和 <code class="highlighter-rouge">/mnt</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>umount /mnt/home
umount /mnt
</code></pre></div></div>
<p>至此,基本系统安装完毕,重启</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>reboot
</code></pre></div></div>
<hr />
<h2 id="安装图形界面">安装图形界面</h2>
<h3 id="安装-x">安装 X</h3>
<p>安装基础的 Xorg 包</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> xorg-server xorg-xinit xorg-utils xorg-server-utils
</code></pre></div></div>
<p>安装 mesa 以获得 3D 支持</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> mesa
</code></pre></div></div>
<h3 id="显卡驱动">显卡驱动</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> xf86-video-ati lib32-ati-dri
<span class="nb">sudo </span>pacman <span class="nt">-S</span> xf86-video-intel lib32-intel-dri
</code></pre></div></div>
<h3 id="触摸板驱动">触摸板驱动</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> xf86-input-synaptics
</code></pre></div></div>
<h3 id="声音">声音</h3>
<p>安装 alsa-utils</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> alsa-utils
</code></pre></div></div>
<p>解除静音</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>amixer sset Master unmute
</code></pre></div></div>
<h3 id="字体">字体</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> ttf-dejavu wqy-zenhei wqy-microhei
</code></pre></div></div>
<h3 id="安装-xfce4">安装 Xfce4</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> xfce4
</code></pre></div></div>
<p>也可以只安装部分 Xfce4 的软件包</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> tumbler xfce4-appfinder xfce4-mixer <span class="se">\</span>
xfce4-power-manager <span class="se">\</span>
xfce4-session xfce4-settings <span class="se">\</span>
xfdesktop xfwm4 xfwm4-themes
</code></pre></div></div>
<h3 id="安装-slim">安装 Slim</h3>
<p>安装</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> slim
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>slim.service
</code></pre></div></div>
<p>配置<code class="highlighter-rouge">~/.xinitrc</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cp</span> /etc/skel/.xinitrc ~/
<span class="nb">chmod</span> +x ~/.xinitrc
</code></pre></div></div>
<p>然后编辑 <code class="highlighter-rouge">~/.xinitrc</code>,在最后添加 <code class="highlighter-rouge">exec startxfce4</code></p>
<h3 id="安装-cairo-dock">安装 cairo-dock</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> cairo-dock cairo-dock-plugins
</code></pre></div></div>
<h3 id="修改-x11-键盘映射">修改 X11 键盘映射</h3>
<p>把 <code class="highlighter-rouge">Caps Lock</code> 改为 <code class="highlighter-rouge">Ctrl</code>,把下面的命令添加到开机自启动</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>setxkbmap <span class="nt">-option</span> caps:ctrl_modifier
</code></pre></div></div>
<h3 id="安装-fcitx输入法">安装 fcitx输入法</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> fcitx fcitx-configtool fcitx-gtk2 <span class="se">\</span>
fcitx-gtk3 fcitx-qt4 fcitx-qt5
</code></pre></div></div>
<p>在 <code class="highlighter-rouge">~/.xinitrc</code> 中加入如下3行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">GTK_IM_MODULE</span><span class="o">=</span>fcitx
<span class="nb">export </span><span class="nv">QT_IM_MODULE</span><span class="o">=</span>fcitx
<span class="nb">export </span><span class="nv">XMODIFIERS</span><span class="o">=</span><span class="s2">"@im=fcitx"</span>
</code></pre></div></div>
<h3 id="ntfs-与自动挂载">NTFS 与自动挂载</h3>
<p>安装ntfs-3g、gvfs</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> ntfs-3g gvfs
</code></pre></div></div>
<p>在文件夹 <code class="highlighter-rouge">/usr/share/polkit-1/rules.d/</code> 中,创建文件 <code class="highlighter-rouge">10-drives.rules</code>,添加以下内容</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">polkit</span><span class="p">.</span><span class="n">addRule</span><span class="p">(</span><span class="n">function</span><span class="p">(</span><span class="n">action</span><span class="p">,</span> <span class="n">subject</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">id</span><span class="p">.</span><span class="n">indexOf</span><span class="p">(</span><span class="s">"org.freedesktop.udisks2."</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">){</span>
<span class="k">return</span> <span class="n">polkit</span><span class="p">.</span><span class="n">Result</span><span class="p">.</span><span class="n">YES</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">);</span>
</code></pre></div></div>
<hr />
<h2 id="常用软件">常用软件</h2>
<h3 id="vim">Vim</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> vim
</code></pre></div></div>
<h3 id="git">Git</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> git
</code></pre></div></div>
<h3 id="视频播放器">视频播放器</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> smplayer mplayer-vaapi libva-intel-driver
</code></pre></div></div>
<p>在 SMPlyaer 中:选项–>首选项–>常规–>视频,在输出驱动中选 <code class="highlighter-rouge">vaapi</code></p>
<h3 id="gimp">Gimp</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> gimp
</code></pre></div></div>
<h3 id="gparted">GParted</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> gparted
</code></pre></div></div>
<h3 id="yaourt">Yaourt</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://aur.archlinux.org/packages/pa/package-query/package-query.tar.gz
<span class="nb">tar</span> <span class="nt">-zxf</span> package-query.tar.gz
<span class="nb">cd </span>package-query
makepkg <span class="nt">-si</span>
wget https://aur.archlinux.org/packages/ya/yaourt/yaourt.tar.gz
<span class="nb">tar</span> <span class="nt">-zxf</span> yaourt.tar.gz
<span class="nb">cd </span>yaourt
makepkg <span class="nt">-si</span>
</code></pre></div></div>
<h3 id="create_ap-创建wifi热点">create_ap (创建WiFi热点)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> create_ap
</code></pre></div></div>
<h3 id="搜狗拼音输入法">搜狗拼音输入法</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> fcitx-sogoupinyin
</code></pre></div></div>
<h3 id="qt-creator">Qt Creator</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> qtcreator-qt4
</code></pre></div></div>
<h3 id="google-chrome-浏览器">Google Chrome 浏览器</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> google-chrome
</code></pre></div></div>
<h3 id="wps-office">WPS Office</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> kingsoft-office
</code></pre></div></div>
<h3 id="haroopad-markdown编辑器">Haroopad (Markdown编辑器)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> haroopad
</code></pre></div></div>
<h3 id="豆瓣-fm">豆瓣 FM</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> qdoubamfm-git
</code></pre></div></div>
<hr />
<h2 id="游戏">游戏</h2>
<h3 id="steam">Steam</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> steam
</code></pre></div></div>
<h3 id="片轮少女">片轮少女</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> katawa-shoujo
</code></pre></div></div>
<h3 id="黏黏世界">黏黏世界</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> worldofgoo
</code></pre></div></div>
<h3 id="仙剑奇侠传一">仙剑奇侠传一</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> sdlpal-git
</code></pre></div></div>
<hr />
<h2 id="优化配置">优化配置</h2>
<h3 id="cache-directory">Cache Directory</h3>
<p>在 <code class="highlighter-rouge">/etc/fstab</code> 里添加</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Cache Directory</span>
tmpfs /home/shaw/.cache tmpfs <span class="nv">mode</span><span class="o">=</span>1777,noatime 0 0
</code></pre></div></div>
<h3 id="配置-makepkg">配置 makepkg</h3>
<p>编辑 <code class="highlighter-rouge">/etc/makepkg.conf</code>,做以下修改:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">CFLAGS</span><span class="p">=</span><span class="s">"-march=native -mtls-dialect=gnu2 -O2 -pipe"</span>
<span class="py">CXXFLAGS</span><span class="p">=</span><span class="s">"-march=native -mtls-dialect=gnu2 -O2 -pipe"</span>
<span class="py">MAKEFLAGS</span><span class="p">=</span><span class="s">"-j5"</span>
<span class="py">BUILDDIR</span><span class="p">=</span><span class="s">"/tmp/makepkg"</span>
</code></pre></div></div>
<h3 id="配置-qmake">配置 qmake</h3>
<p><strong>qmake-qt4</strong></p>
<ul>
<li>
<p><code class="highlighter-rouge">/usr/share/qt4/mkspecs/common/gcc-base.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>QMAKE_CFLAGS += -mtls-dialect=gnu2 -pipe
QMAKE_CFLAGS_RELEASE += -march=native -mtls-dialect=gnu2 -O2 -pipe
</code></pre></div> </div>
</li>
<li>
<p><code class="highlighter-rouge">/usr/share/qt4/mkspecs/common/g++-base.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -march=native -mtls-dialect=gnu2 -O2 -pipe -g
</code></pre></div> </div>
</li>
</ul>
<p><strong>qmake-qt5</strong></p>
<ul>
<li>
<p><code class="highlighter-rouge">/usr/lib/qt/mkspecs/common/gcc-base.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>QMAKE_CFLAGS_OPTIMIZE += -march=native -mtls-dialect=gnu2 -O2 -pipe
</code></pre></div> </div>
</li>
</ul>
<h3 id="配置外观">配置外观</h3>
<p><strong>安装 Gtk 主题</strong></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> gtk-theme-vimix
</code></pre></div></div>
<p><strong>安装 X11鼠标主题</strong></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yaourt <span class="nt">-S</span> xcursor-oxy-neon
</code></pre></div></div>