24.03.2015 Views

Unix Toolbox - 中文版 - LinuxTone.Org

Unix Toolbox - 中文版 - LinuxTone.Org

Unix Toolbox - 中文版 - LinuxTone.Org

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

UNIX TOOLBOX - 中 文 版<br />

这 是 一 份 收 集 <strong>Unix</strong>/Linux/BSD 命 令 和 任 务 的 文 档 , 它 有 助 于 高 级 用 户 或 IT 工 作 。 它 是 一 份 简 明 扼 要 的 实 用 指 南 ,<br />

当 然 读 者 应 该 知 道 他 / 她 在 干 什 么 。<br />

1. 系 统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

2. 进 程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

3. 文 件 系 统 . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

4. 网 络 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

5. SSH SCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

6. 使 用 SSH 建 立 VPN . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

7. RSYNC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

8. SUDO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

9. 文 件 加 密 . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

10. 分 区 加 密 . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

11. SSL 认 证 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

12. CVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

13. SVN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

14. 实 用 命 令 . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

15. 软 件 安 装 . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

16. 媒 体 转 换 . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

17. 打 印 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

18. 数 据 库 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

19. 磁 盘 限 额 . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

20. Shells . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

21. 脚 本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

22. 编 程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />

23. 在 线 帮 助 . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

<strong>Unix</strong> <strong>Toolbox</strong> 版 本 :12<br />

你 可 以 到 http://cb.vu/unixtoolbox.xhtml 找 到 本 文 档 的 最 新 版 。PDF 版 本 可 以 替 换 链 接 中 的 .xhtml 为 .pdf<br />

, 小 册 子 版 本 可 以 替 换 成 .book.pdf 。 用 双 面 打 印 机 可 将 小 册 子 打 印 成 册 。<br />

错 误 报 告 和 评 论 是 最 欢 迎 的 - c@cb.vu Colin Barschel.<br />

你 可 以 到 http://code.google.com/p/unixtoolboxcn/ 找 到 中 文 最 新 版 。<br />

也 可 到 我 的 主 页 获 取 http://silenceisdefeat.org/~greco/unixtoolbox_zh_CN.xhtml<br />

关 于 中 文 版 的 任 何 错 误 和 修 正 请 发 送 E-Mail 到 "Greco Shi"


1 系 统<br />

硬 件 (p2) | 状 态 信 息 (p2) | 用 户 (p3) | 限 制 (p3) | 运 行 级 别 (p4) | root 密 码 (p5) | 编 译 内 核 (p6)<br />

正 在 运 行 的 内 核 和 系 统 信 息<br />

# uname -a # 获 取 内 核 版 本 ( 和 BSD 版 本 )<br />

# lsb_release -a # 显 示 任 何 LSB 发 行 版 版 本 信 息<br />

# cat /etc/SuSE-release # 获 取 SuSE 版 本<br />

# cat /etc/debian_version # 获 取 Debian 版 本<br />

使 用 /etc/DISTR-release 其 中 DISTR( 发 行 代 号 )= lsb (Ubuntu), redhat, gentoo, mandrake, sun<br />

(Solaris), 等 等 。<br />

# uptime # 显 示 系 统 开 机 运 行 到 现 在 经 过 的 时 间<br />

# hostname # 显 示 系 统 主 机 名<br />

# hostname -i # 显 示 主 机 的 IP 地 址<br />

# man hier # 描 述 文 件 系 统 目 录 结 构<br />

# last reboot # 显 示 系 统 最 后 重 启 的 历 史 记 录<br />

1.1 硬 件 信 息<br />

内 核 检 测 到 的 硬 件 信 息<br />

# dmesg # 检 测 到 的 硬 件 和 启 动 的 消 息<br />

# lsdev<br />

1<br />

# 关 于 已 安 装 硬 件 的 信 息<br />

# dd if=/dev/mem bs=1k skip=768 count=256 2>/dev/null | strings -n 8 # 读 取 BIOS 信 息<br />

Linux<br />

# cat /proc/cpuinfo # CPU 讯 息<br />

# cat /proc/meminfo # 内 存 信 息<br />

# grep MemTotal /proc/meminfo # 显 示 物 理 内 存 大 小<br />

# watch -n1 'cat /proc/interrupts' # 监 控 内 核 处 理 的 所 有 中 断<br />

# free -m # 显 示 已 用 和 空 闲 的 内 存 信 息 (-m 为 MB) 2<br />

# cat /proc/devices # 显 示 当 前 核 心 配 置 的 设 备<br />

# lspci -tv # 显 示 PCI 设 备<br />

# lsusb -tv # 显 示 USB 设 备<br />

# lshal # 显 示 所 有 设 备 属 性 列 表<br />

# dmidecode # 显 示 从 BIOS 中 获 取 的 硬 件 信 息<br />

FreeBSD<br />

— 系 统 —<br />

# sysctl hw.model # CPU 讯 息<br />

# sysctl hw # 得 到 很 多 硬 件 信 息<br />

# sysctl vm # 虚 拟 内 存 使 用 情 况<br />

# dmesg | grep "real mem" # 物 理 内 存<br />

# sysctl -a | grep mem # 内 核 内 存 的 设 置 和 信 息<br />

# sysctl dev # 显 示 当 前 核 心 配 置 的 设 备<br />

# pciconf -l -cv # 显 示 PCI 设 备<br />

# usbdevs -v # 显 示 USB 设 备<br />

# atacontrol list # 显 示 ATA 设 备<br />

1.2 显 示 状 态 信 息<br />

以 下 的 命 令 有 助 于 找 出 正 在 系 统 中 运 行 着 的 程 序 。<br />

# top # 显 示 和 更 新 使 用 cpu 最 多 的 进 程<br />

# mpstat 1 # 显 示 进 程 相 关 的 信 息<br />

# vmstat 2 # 显 示 虚 拟 内 存 的 状 态 信 息<br />

# iostat 2 # 显 示 I/O 状 态 信 息 (2 秒 间 隙 )<br />

1. 译 注 : 许 多 Linux 发 行 版 需 要 自 行 安 装 , 如 :apt-get install procinfo<br />

2. 译 注 : 包 括 SWAP 分 区<br />

2


— 系 统 —<br />

# systat -vmstat 1 # 显 示 BSD 系 统 状 态 信 息 (1 秒 间 隙 )<br />

# systat -tcp 1 # 显 示 BSD TCP 连 接 信 息 ( 也 可 以 试 试 -ip)<br />

# systat -netstat 1 # 显 示 BSD 当 前 网 络 连 接 信 息<br />

# systat -ifstat 1 # 显 示 BSD 当 前 网 卡 带 宽 信 息<br />

# systat -iostat 1 # 显 示 BSD CPU 和 磁 盘 使 用 情 况<br />

# tail -n 500 /var/log/messages # 显 示 最 新 500 条 内 核 / 系 统 日 志 的 信 息<br />

# tail /var/log/warn # 显 示 系 统 警 告 信 息 ( 看 syslog.conf)<br />

1.3 用 户<br />

# id # 显 示 当 前 用 户 和 用 户 组 的 ID<br />

# last<br />

3<br />

# 列 出 目 前 与 过 去 登 入 系 统 的 用 户 相 关 信 息<br />

# who # 显 示 目 前 登 入 系 统 的 用 户 信 息<br />

# groupadd admin # 建 立 新 组 "admin" 和 添 加 新 用 户 colin 并 加 入 admin 用 户 组 (Linux/Solaris)<br />

# useradd -c "Colin Barschel" -g admin -m colin<br />

# userdel colin # 删 除 用 户 colin(Linux/Solaris)<br />

# adduser joe # FreeBSD 添 加 用 户 joe( 交 互 式 )<br />

# rmuser joe # FreeBSD 删 除 用 户 joe( 交 互 式 )<br />

# pw groupadd admin # 在 FreeBSD 上 使 用 pw<br />

# pw groupmod admin -m newmember # 添 加 新 用 户 到 一 个 组<br />

# pw useradd colin -c "Colin Barschel" -g admin -m -s /bin/tcsh<br />

# pw userdel colin; pw groupdel admin<br />

加 密 过 的 密 码 存 储 在 /etc/shadow (Linux and Solaris) 或 /etc/master.passwd (FreeBSD) 中 . 如 果 手 动 修<br />

改 了 master.passwd, 需 要 运 行 # pwd_mkdb -p master.passwd 来 重 建 数 据 库 。<br />

使 用 nologin 来 临 时 阻 止 所 有 用 户 登 录 (root 除 外 )。 用 户 登 录 时 将 会 显 示 nologin 中 的 信 息 。<br />

# echo "Sorry no login now" > /etc/nologin # (Linux)<br />

# echo "Sorry no login now" > /var/run/nologin # (FreeBSD)<br />

1.4 限 制<br />

某 些 应 用 程 序 需 要 设 置 可 打 开 最 大 文 件 和 socket 数 量 ( 像 代 理 服 务 器 , 数 据 库 )。 默 认 限 制 通 常 很 低 。<br />

Linux<br />

每 shell/ 脚 本<br />

shell 的 限 制 是 受 ulimit 支 配 的 。 使 用 ulimit -a 可 查 看 其 状 态 信 息 。 举 个 例 子 , 改 变 可 打 开 最 大 文 件 数 从<br />

1024 到 10240, 可 以 这 么 做 :<br />

# ulimit -n 10240 # 这 只 在 shell 中 有 用<br />

ulimit 命 令 可 以 使 用 在 脚 本 中 来 更 改 对 此 脚 本 的 限 制 。<br />

每 用 户 / 进 程<br />

登 录 用 户 和 应 用 程 序 的 限 制 可 以 在 /etc/security/limits.conf 中 配 置 。 举 个 例 子 :<br />

# cat /etc/security/limits.conf<br />

* hard nproc 250 # 限 制 所 有 用 户 进 程 数<br />

asterisk hard nofile 409600 # 限 制 应 用 程 序 可 打 开 最 大 文 件 数<br />

系 统 级<br />

用 sysctl 来 设 置 内 核 限 制 。 要 使 其 永 久 , 可 以 在 /etc/sysctl.conf 中 进 行 配 置 。<br />

# sysctl -a # 显 示 所 有 系 统 限 制<br />

# sysctl fs.file-max # 显 示 系 统 最 大 文 件 打 开 数<br />

# sysctl fs.file-max=102400 # 更 改 系 统 最 大 文 件 打 开 数<br />

# cat /etc/sysctl.conf<br />

fs.file-max=102400<br />

# 在 sysctl.conf 中 的 永 久 项<br />

# cat /proc/sys/fs/file-nr # 在 使 用 的 文 件 句 柄 数<br />

3. 译 注 : 单 独 执 行 last 指 令 , 它 会 读 取 位 于 /var/log 目 录 下 , 名 称 为 wtmp 的 文 件 , 并 把 该 给 文 件 的 内 容 记 录 的 登 入 系 统 的 用 户 名 单 全 部 显 示 出 来 。<br />

3


— 系 统 —<br />

FreeBSD<br />

每 shell/ 脚 本<br />

在 csh 或 tcsh 中 使 用 limits 命 令 , 在 sh 或 bash 中 使 用 ulimit 命 令 。<br />

每 用 户 / 进 程<br />

在 /etc/login.conf 中 配 置 登 录 后 的 默 认 限 制 。 未 作 限 制 的 值 为 系 统 最 大 限 制 值 。<br />

系 统 级<br />

内 核 限 制 同 样 使 用 sysctl 来 设 置 。 永 久 配 置 , 在 /etc/sysctl.conf 或 /boot/loader.conf 中 。 其 语 法 与<br />

Linux 相 同 , 只 是 键 值 不 同 。<br />

# sysctl -a # 显 示 所 有 系 统 限 制<br />

# sysctl kern.maxfiles=XXXX # 最 大 文 件 描 述 符 数<br />

kern.ipc.nmbclusters=32768<br />

# 在 /etc/sysctl.conf 中 的 永 久 项<br />

kern.maxfiles=65536 # Squid 4 通 常 用 这 个 值<br />

kern.maxfilesperproc=32768<br />

kern.ipc.somaxconn=8192<br />

# TCP 列 队 。apache/sendmail 最 好 用 这 个 值<br />

# sysctl kern.openfiles # 在 使 用 的 文 件 描 述 符 数<br />

# sysctl kern.ipc.numopensockets # 已 经 开 启 的 socket 数 目<br />

详 情 请 看 FreeBSD 手 册 11 章 5<br />

。<br />

Solaris<br />

在 /etc/system 中 的 下 列 设 置 , 会 提 高 每 个 进 程 可 以 打 开 最 大 文 件 描 述 符 的 数 量 :<br />

set rlim_fd_max = 4096<br />

set rlim_fd_cur = 1024<br />

1.5 运 行 级 别<br />

Linux<br />

# 一 个 进 程 可 以 打 开 文 件 描 述 符 的 " 硬 " 限 制<br />

# 一 个 进 程 可 以 打 开 文 件 描 述 符 的 " 软 " 限 制<br />

一 旦 内 核 加 载 完 成 , 内 核 会 启 动 init 进 程 , 然 后 运 行 rc 6 脚 本 , 之 后 运 行 所 有 属 于 其 运 行 级 别 的 命 令 脚 本 。 这<br />

些 脚 本 都 储 存 在 /etc/rc.d/rcN.d 中 (N 代 表 运 行 级 别 ), 并 且 都 建 立 着 到 /etc/init.d 子 目 录 中 命 令 脚 本 程 序<br />

的 符 号 链 接 。<br />

默 认 运 行 级 别 配 置 在 /etc/inittab 中 。 它 通 常 为 3 或 5:<br />

# grep default: /etc/inittab<br />

id:3:initdefault:<br />

可 以 使 用 init 来 改 变 当 前 运 行 级 别 。 举 个 例 子 :<br />

# init 5 # 进 入 运 行 级 别 5<br />

运 行 级 别 列 表 如 下 :<br />

0 系 统 停 止<br />

1 进 入 单 用 户 模 式 ( 也 可 以 是 S)<br />

2 没 有 NFS 特 性 的 多 用 户 模 式<br />

3 完 全 多 用 户 模 式 ( 正 常 操 作 模 式 )<br />

4 未 使 用<br />

5 类 似 于 级 别 3, 但 提 供 XWindow 系 统 登 录 环 境<br />

6 重 新 启 动 系 统<br />

使 用 chkconfig 工 具 控 制 程 序 在 一 个 运 行 级 别 启 动 和 停 止 。<br />

# chkconfig --list # 列 出 所 有 init 脚 本<br />

# chkconfig --list sshd # 查 看 sshd 在 各 个 运 行 级 别 中 的 启 动 配 置<br />

# chkconfig sshd --level 35 on # 对 sshd 在 级 别 3 和 5 下 创 建 启 动 项<br />

# chkconfig sshd off # 在 所 有 的 运 行 级 别 下 禁 用 sshd<br />

4. 译 注 : 代 理 服 务 器<br />

5.http://www.freebsd.org/handbook/configtuning-kernel-limits.html<br />

6. 译 注 :/etc/rc.d/rc<br />

4


Debian 和 基 于 Debian 发 行 版 像 Ubuntu 或 Knoppix 使 用 命 令 update-rc.d 来 管 理 运 行 级 别 脚 本 。 默 认 启 动 为<br />

2,3,4 和 5, 停 止 为 0,1 和 6。<br />

# update-rc.d sshd defaults # 设 置 sshd 为 默 认 启 动 级 别<br />

# update-rc.d sshd start 20 2 3 4 5 . stop 20 0 1 6 . # 用 显 示 参 数<br />

# update-rc.d -f sshd remove # 在 所 有 的 运 行 级 别 下 禁 用 sshd<br />

# shutdown -h now ( 或 者 # poweroff) # 关 闭 停 止 系 统<br />

FreeBSD<br />

BSD 启 动 步 骤 不 同 于 SysV, 她 没 有 运 行 级 别 。 她 的 启 动 状 态 ( 单 用 户 , 有 或 没 有 XWindow) 被 配 置 在 /etc/<br />

ttys 中 。 所 有 的 系 统 脚 本 都 位 于 /etc/rc.d/ 中 , 第 三 方 应 用 程 序 位 于 /usr/local/etc/rc.d/ 中 。service 的 启<br />

动 顺 序 被 配 置 在 /etc/rc.conf 和 /etc/rc.conf.local 中 。 默 认 行 为 可 在 /etc/defaults/rc.conf 中 进 行 配<br />

置 。 这 些 脚 本 至 少 响 应 start|stop|status.<br />

# /etc/rc.d/sshd status<br />

sshd is running as pid 552.<br />

# shutdown now # 进 入 单 用 户 模 式<br />

# exit # 返 回 到 多 用 户 模 式<br />

# shutdown -p now # 关 闭 停 止 系 统<br />

# shutdown -r now # 重 新 启 动 系 统<br />

同 样 可 以 使 用 进 程 init 进 入 下 列 状 态 级 别 。 举 个 例 子 : # init 6 为 重 启 。<br />

0 停 止 系 统 并 关 闭 电 源 ( 信 号 USR2)<br />

1 进 入 单 用 户 模 式 ( 信 号 TERM)<br />

6 重 新 启 动 ( 信 号 INT)<br />

c 阻 止 进 一 步 登 录 ( 信 号 TSTP)<br />

q 重 新 检 查 ttys(5) 文 件 ( 信 号 HUP)<br />

1.6 重 设 root 密 码<br />

Linux 方 法 1<br />

在 引 导 加 载 器 (lilo 或 grub) 中 , 键 入 如 下 启 选 项 :<br />

init=/bin/sh<br />

内 核 会 挂 载 root 分 区 , 进 程 init 会 启 动 bourne shell 而 不 是 rc, 然 后 是 运 行 级 别 。 使 用 命 令 passwd 设<br />

置 密 码 然 后 重 启 。 别 忘 了 需 要 在 单 用 户 模 式 下 做 这 些 动 作 。<br />

如 果 重 启 后 root 分 区 被 挂 载 为 只 读 , 重 新 挂 在 它 为 读 写 :<br />

# mount -o remount,rw /<br />

# passwd # 或 者 删 除 root 密 码 (/etc/shadow)<br />

# sync; mount -o remount,ro / # sync 在 重 新 挂 在 为 只 读 之 前 sync 一 下<br />

# reboot<br />

FreeBSD 和 Linux 方 法 2<br />

— 系 统 —<br />

FreeBSD 不 会 让 你 这 么 做 。 解 决 方 案 是 用 其 他 操 作 系 统 ( 像 系 统 紧 急 修 复 光 盘 ) 挂 载 root 分 区 , 然 后 更 改 密 码 。<br />

• 用 live cd 或 安 装 盘 启 动 进 入 修 复 模 式 后 , 会 得 到 一 个 shell。<br />

• 用 fdisk 查 找 root 分 区 。 比 如 :fdisk /dev/sda<br />

• 挂 载 它 并 使 用 chroot 命 令 :<br />

# mount -o rw /dev/ad4s3a /mnt<br />

# chroot /mnt # 改 变 程 序 执 行 时 所 参 考 的 根 目 录 位 置 为 /mnt<br />

# passwd<br />

# reboot<br />

5


— 进 程 —<br />

1.7 内 核 模 块<br />

Linux<br />

# lsmod # 列 出 所 有 已 载 入 内 核 的 模 块<br />

# modprobe isdn # 载 入 isdn 模 块<br />

FreeBSD<br />

# kldstat # 列 出 所 有 已 载 入 内 核 的 模 块<br />

# kldload crypto # 载 入 crypto 模 块<br />

1.8 编 译 内 核<br />

Linux<br />

# cd /usr/src/linux<br />

# make mrproper # 清 除 所 有 东 西 , 包 括 配 置 文 件<br />

# make oldconfig # 从 当 前 内 核 配 置 文 件 的 基 础 上 创 建 一 个 新 的 配 置 文 件<br />

# make menuconfig # 或 者 xconfig (Qt) 或 者 gconfig (GTK)<br />

# make # 创 建 一 个 已 压 缩 的 内 核 映 像 文 件<br />

# make modules # 编 译 模 块<br />

# make modules_install # 安 装 模 块<br />

# make install # 安 装 内 核<br />

# reboot<br />

FreeBSD<br />

要 改 变 和 重 建 内 核 , 需 要 拷 贝 源 配 置 文 件 然 后 编 辑 它 。 当 然 也 可 以 直 接 编 辑 GENERIC 文 件 。<br />

# cd /usr/src/sys/i386/conf/<br />

# cp GENERIC MYKERNEL<br />

# cd /usr/src<br />

# make buildkernel KERNCONF=MYKERNEL<br />

# make installkernel KERNCONF=MYKERNEL<br />

要 重 建 完 全 的 操 作 系 统 :<br />

# make buildworld # 构 建 完 全 的 系 统 , 但 不 是 内 核<br />

# make buildkernel # 使 用 KERNCONF 配 置 文 件 编 译 内 核<br />

# make installkernel<br />

# reboot<br />

# mergemaster -p # 建 立 临 时 根 环 境 并 比 对 系 统 配 置 文 件<br />

# make installworld<br />

# mergemaster # 升 级 所 有 配 置 和 其 他 文 件<br />

# reboot<br />

对 于 源 的 一 些 小 改 动 , 有 时 候 简 单 的 命 令 就 足 够 了 :<br />

# make kernel world # 编 译 并 安 装 内 核 和 系 统<br />

# mergemaster<br />

# reboot<br />

2 进 程<br />

列 表 (p6) | 优 先 级 (p7) | 后 台 / 前 台 (p7) | Top (p7) | Kill (p8)<br />

2.1 进 程 列 表<br />

PID 是 每 个 进 程 唯 一 号 码 。 使 用 ps 获 取 所 有 正 在 运 行 的 进 程 列 表 。<br />

# ps -auxefw # 所 有 正 在 运 行 进 程 的 详 尽 列 表<br />

6


然 而 , 更 典 型 的 用 法 是 使 用 管 道 或 者 pgrep:<br />

# ps axww | grep cron<br />

586 ?? Is 0:01.48 /usr/sbin/cron -s<br />

# ps aux | grep 'ss[h]' # Find all ssh pids without the grep pid<br />

# pgrep -l sshd # 查 找 所 有 进 程 名 中 有 sshd 的 进 程 ID<br />

# echo $$ # The PID of your shell<br />

# fuser -va 22/tcp # 列 出 使 用 端 口 22 的 进 程<br />

# fuser -va /home # 列 出 访 问 /home 分 区 的 进 程<br />

# strace df # 跟 踪 系 统 调 用 和 信 号<br />

# truss df # 同 上 (FreeBSD/Solaris/ 类 <strong>Unix</strong>)<br />

# history | tail -50 # 显 示 最 后 50 个 使 用 过 的 命 令<br />

2.2 优 先 级<br />

用 renice 更 改 正 在 运 行 进 程 的 优 先 级 。 负 值 是 更 高 的 优 先 级 , 最 小 为 -20, 其 正 值 与 "nice" 值 的 意 义 相 同 7<br />

。<br />

# renice -5 586 # 更 强 的 优 先 级<br />

586: old priority 0, new priority -5<br />

使 用 nice 命 令 启 动 一 个 已 定 义 优 先 级 的 进 程 。 正 值 为 低 优 先 级 , 负 值 为 高 优 先 级 。 确 定 你 知 道 /usr/bin/<br />

nice 或 者 使 用 shell 内 置 命 令 8<br />

(# which nice)。<br />

# nice -n -5 top # 更 高 优 先 级 (/usr/bin/nice)<br />

# nice -n 5 top # 更 低 优 先 级 (/usr/bin/nice)<br />

# nice +5 top # tcsh 内 置 nice 命 令 ( 同 上 )<br />

nice 可 以 影 响 CPU 的 调 度 , 另 一 个 实 用 命 令 ionice 9 可 以 调 度 磁 盘 IO。This is very useful for intensive<br />

IO application which can bring a machine to its knees while still in a lower priority. 此 命 令 仅 可<br />

在 Linux (AFAIK) 上 使 用 。 你 可 以 选 择 一 个 类 型 (idle - best effort - real time), 它 的 man 页 很 短 并 有 很<br />

好 的 解 释 。<br />

# ionice c3 -p123 # 给 pid 123 设 置 为 idle 类 型<br />

# ionice -c2 -n0 firefox # 用 best effort 类 型 运 行 firefox 并 且 设 为 高 优 先 级<br />

# ionice -c3 -p$$ # 将 当 前 的 进 程 (shell) 的 磁 盘 IO 调 度 设 置 为 idle 类 型<br />

例 中 最 后 一 条 命 令 对 于 编 译 ( 或 调 试 ) 一 个 大 型 项 目 会 非 常 有 用 。 每 一 个 运 行 于 此 shell 的 命 令 都 会 有 一 个 较 低<br />

的 优 先 级 , 但 并 不 妨 碍 这 个 系 统 。$$ 是 你 shell 的 pid ( 试 试 echo $$)。<br />

2.3 前 台 / 后 台<br />

当 一 个 进 程 在 shell 中 已 运 行 , 可 以 使 用 [Ctrl]-[Z] (^Z), bg 和 fg 来 调 入 调 出 前 后 台<br />

10<br />

。 举 个 例 子 : 启 动<br />

2 个 进 程 , 调 入 后 台 。 使 用 jobs 列 出 后 台 列 表 , 然 后 再 调 入 一 个 进 程 到 前 台 。<br />

# ping cb.vu > ping.log<br />

^Z # ping 使 用 [Ctrl]-[Z] 来 暂 停 ( 停 止 )<br />

# bg # 调 入 后 台 继 续 运 行<br />

# jobs -l # 后 台 进 程 列 表<br />

[1] - 36232 Running ping cb.vu > ping.log<br />

[2] + 36233 Suspended (tty output) top<br />

# fg %2 # 让 进 程 2 返 回 到 前 台 运 行<br />

使 用 nohup 开 启 一 个 持 续 运 行 的 进 程 直 到 shell 被 关 闭 ( 避 免 挂 断 )。<br />

# nohup ping -i 60 > ping.log &<br />

2.4 Top<br />

top 程 序 用 来 实 时 显 示 系 统 中 各 个 进 程 的 运 行 信 息 。<br />

— 进 程 —<br />

7. 译 注 : 进 程 的 优 先 级 通 常 被 称 作 它 的 nice 值 。 用 户 只 能 对 自 己 所 有 的 进 程 使 用 renice 命 令 ,root 用 户 可 以 在 任 何 进 程 上 使 用 renice 命<br />

令 , 只 有 root 用 户 才 能 提 高 进 程 的 优 先 级<br />

8. 译 注 : 要 查 看 所 有 shell 内 置 命 令 , 可 运 行 # info bash builtin<br />

9. 译 注 : 此 命 令 仅 可 工 作 在 2.6.13 及 以 上 内 核 版 本 上 , 并 且 采 用 了 CFQ 的 IO 调 度 方 式 。 通 过 #cat /sys/block/[sh]d[a-z]*/queue/<br />

scheduler 命 令 可 以 得 知 你 的 系 统 采 用 了 什 么 样 的 调 度 算 法<br />

10. 译 注 : 在 命 令 后 面 加 & 可 直 接 使 其 在 后 台 运 行 。<br />

7


# top<br />

当 top 在 运 行 的 时 候 , 按 下 h 11 键 会 显 示 帮 助 画 面 。 常 用 键 如 下 :<br />

• u [ 用 户 名 ] 只 显 示 属 于 此 用 户 的 进 程 。 使 用 + 或 者 空 白 可 以 查 看 所 有 用 户<br />

• k [PID] 结 束 PID 进 程<br />

• 1 12 显 示 所 有 进 程 状 态 信 息 ( 只 有 Linux)<br />

• R 将 当 前 排 序 倒 转<br />

2.5 Kill 命 令 与 信 号<br />

使 用 kill 或 killall 终 止 或 发 送 一 个 信 号 给 进 程 。<br />

# ping -i 60 cb.vu > ping.log &<br />

[1] 4712<br />

# kill -s TERM 4712 # 同 kill -15 4712<br />

# killall -1 httpd # 发 送 HUP 信 号 终 止 进 程 httpd<br />

# pkill -9 http # 发 送 TERM 信 号 终 止 包 含 http 的 进 程<br />

# pkill -TERM -u www # 发 送 TERM 信 号 终 止 www 所 有 者 进 程<br />

# fuser -k -TERM -m /home # 终 止 所 有 访 问 /home 的 进 程 ( 卸 载 该 分 区 前 )<br />

下 面 是 一 些 重 要 的 信 号 :<br />

1 HUP ( 挂 起 )<br />

2 INT ( 中 断 )<br />

3 QUIT ( 退 出 )<br />

9 KILL (KILL 信 号 不 能 被 捕 捉 , 不 能 被 忽 略 。)<br />

15 TERM ( 软 件 终 止 信 号 )<br />

3 文 件 系 统<br />

磁 盘 信 息 (p9) | Boot (p9) | 磁 盘 使 用 情 况 (p9) | 已 打 开 的 文 件 (p9) | 挂 载 / 重 挂 (p10) | 挂 载 SMB<br />

(p11) | 挂 载 映 像 文 件 (p11) | Burn ISO (p12) | Create image (p13) | Memory disk (p13) | Disk<br />

performance (p14)<br />

3.1 权 限<br />

— 文 件 系 统 —<br />

用 chmod 和 chown 更 改 访 问 权 限 和 所 有 权 。 对 于 所 有 用 户 的 默 认 掩 码 (umask) 可 以 在 /etc/profile (Linux)<br />

或 /etc/login.conf (FreeBSD) 中 修 改 。 其 默 认 掩 码 (umask) 通 常 为 022。 掩 码 可 以 和 777 做 减 法 , 从 而 得 到 755<br />

的 权 限 。<br />

1 --x 执 行 # Mode 764 = 执 行 / 读 / 写 | 读 / 写 | 读<br />

2 -w- 写 # |--- 所 有 者 |--- 用 户 组 |--- 其 他 用 户 |<br />

4 r-- 读<br />

ugo=a<br />

u= 所 有 者 , g= 用 户 组 , o= 其 他 用 户 , a= 所 有 用 户<br />

# chmod [OPTION] MODE[,MODE] FILE # MODE 可 以 是 [ugoa]*([-+=]([rwxXst]))<br />

# chmod 640 /var/log/maillog # 更 改 maillog 访 问 权 限 为 -rw-r-----<br />

# chmod u=rw,g=r,o= /var/log/maillog # 同 上<br />

# chmod -R o-r /home/* # 递 归 去 除 所 有 其 他 用 户 的 可 读 权 限<br />

# chmod u+s /path/to/prog # 在 可 执 行 位 设 置 SUID ( 知 道 你 在 干 什 么 ! 13 )<br />

# find / -perm -u+s -print # 查 找 所 有 设 置 过 SUID 位 的 程 序<br />

# chown user:group /path/to/file # 改 变 文 件 的 所 有 者 和 文 件 关 联 的 组<br />

# chgrp group /path/to/file # 改 变 文 件 关 联 的 组<br />

# chmod 640 `find ./ -type f -print` # Change permissions to 640 for all files<br />

# chmod 751 `find ./ -type d -print` # Change permissions to 751 for all directories<br />

11. 译 注 : 也 可 以 是 ?<br />

12. 译 注 : 数 字<br />

13. 当 执 行 一 个 具 有 setuid 权 限 的 文 件 时 , 文 件 的 执 行 过 程 将 具 有 文 件 所 有 者 的 特 权 ( 比 如 root)。 所 以 , 应 尽 量 避 免 不 加 选 择 地 创 建 和 使 用 root 用 户 拥 有 的 seruid<br />

8


— 文 件 系 统 —<br />

3.2 磁 盘 信 息<br />

# diskinfo -v /dev/ad2 # 显 示 磁 盘 信 息 ( 扇 区 / 大 小 ) (FreeBSD)<br />

# hdparm -I /dev/sda # 显 示 IDE/ATA 磁 盘 信 息 (Linux)<br />

# fdisk /dev/ad2 # 显 示 和 修 改 磁 盘 分 区 表<br />

# smartctl -a /dev/ad2 # 显 示 磁 盘 检 测 信 息<br />

3.3 Boot<br />

FreeBSD<br />

如 果 新 内 核 不 能 引 导 , 要 引 导 一 个 旧 内 核 , 停 止 启 动 倒 计 时 , 做 如 下 动 作 :<br />

# unload<br />

# load kernel.old<br />

# boot<br />

3.4 系 统 挂 载 点 / 磁 盘 使 用 情 况<br />

# mount | column -t # 显 示 系 统 已 挂 载 分 区 情 况<br />

# df # 显 示 磁 盘 剩 余 空 间 和 挂 载 的 设 备<br />

# cat /proc/partitions # 显 示 所 有 设 备 的 所 有 分 区 (Linux)<br />

磁 盘 使 用 情 况<br />

# du -sh * # 列 出 当 前 目 录 下 所 有 文 件 夹 大 小<br />

# du -csh # 当 前 目 录 下 所 有 目 录 大 小 总 数<br />

# du -ks * | sort -n -r # 由 大 到 小 排 序 显 示 目 录 大 小<br />

# ls -lSr # 由 小 到 大 显 示 文 件 列 表<br />

3.5 谁 打 开 了 那 些 文 件<br />

对 于 找 出 哪 些 文 件 阻 止 卸 载 分 区 并 给 出 有 代 表 性 的 错 误 是 有 帮 助 的 :<br />

# umount /home/<br />

umount: unmount of /home<br />

failed: Device busy<br />

FreeBSD 和 大 多 数 <strong>Unix</strong><br />

# 不 能 卸 载 , 因 为 有 一 个 文 件 锁 定 了 home<br />

# fstat -f /home # 对 于 一 个 挂 载 点<br />

# fstat -p PID # 对 于 一 个 应 用 程 序 进 程 ID<br />

# fstat -u user # 对 于 一 个 用 户<br />

查 找 已 打 开 日 志 文 件 ( 或 其 他 已 打 开 文 件 ), 比 如 Xorg:<br />

# ps ax | grep Xorg | awk '{print $1}'<br />

1252<br />

# fstat -p 1252<br />

USER CMD PID FD MOUNT INUM MODE SZ|DV R/W<br />

root Xorg 1252 root / 2 drwxr-xr-x 512 r<br />

root Xorg 1252 text /usr 216016 -rws--x--x 1679848 r<br />

root Xorg 1252 0 /var 212042 -rw-r--r-- 56987 w<br />

在 /var 中 的 只 有 一 个 inum 为 212042 的 文 件 :<br />

# find -x /var -inum 212042<br />

/var/log/Xorg.0.log<br />

Linux<br />

使 用 fuser 或 lsof 在 一 个 挂 载 点 中 查 找 已 打 开 的 文 件 :<br />

9


# fuser -m /home # 列 出 访 问 /home 的 进 程<br />

# lsof /home<br />

COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME<br />

tcsh 29029 eedcoba cwd DIR 0,18 12288 1048587 /home/eedcoba (guam:/home)<br />

lsof 29140 eedcoba cwd DIR 0,18 12288 1048587 /home/eedcoba (guam:/home)<br />

关 于 一 个 应 用 程 序 :<br />

ps ax | grep Xorg | awk '{print $1}'<br />

3324<br />

# lsof -p 3324<br />

COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME<br />

Xorg 3324 root 0w REG 8,6 56296 12492 /var/log/Xorg.0.log<br />

关 于 单 个 文 件 :<br />

— 文 件 系 统 —<br />

# lsof /var/log/Xorg.0.log<br />

COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME<br />

Xorg 3324 root 0w REG 8,6 56296 12492 /var/log/Xorg.0.log<br />

3.6 挂 载 / 重 挂 载 一 个 文 件 系 统<br />

举 个 cdrom 的 例 子 。 如 果 已 经 列 于 /etc/fstab 中 :<br />

# mount /cdrom<br />

或 在 /dev/ 中 查 找 设 备 , 亦 或 使 用 dmesg 命 令<br />

FreeBSD<br />

# mount -v -t cd9660 /dev/cd0c /mnt # cdrom<br />

# mount_cd9660 /dev/wcd0c /cdrom # 另 外 一 个 方 法<br />

# mount -v -t msdos /dev/fd0c /mnt # 软 驱<br />

/etc/fstab 中 的 一 条 :<br />

# Device Mountpoint FStype Options Dump Pass#<br />

/dev/acd0 /cdrom cd9660 ro,noauto 0 0<br />

要 允 许 用 户 做 这 些 , 可 以 这 么 做 :<br />

# sysctl vfs.usermount=1 # 或 者 在 /etc/sysctl.conf 中 插 入 一 条 "vfs.usermount=1"<br />

Linux<br />

# mount -t auto /dev/cdrom /mnt/cdrom # 典 型 的 cdrom 挂 载 命 令<br />

# mount /dev/hdc -t iso9660 -r /cdrom # IDE<br />

# mount /dev/sdc0 -t iso9660 -r /cdrom # SCSI<br />

/etc/fstab 中 的 条 目 :<br />

/dev/cdrom /media/cdrom subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec 0 0<br />

用 Linux 挂 载 一 个 FreeBSD 分 区<br />

用 fdisk 查 找 分 区 号 , 这 通 常 是 root 分 区 , 但 也 可 能 是 其 他 BSD slice。 如 果 FreeBSD 有 许 多 slice, 他 们<br />

不 列 于 同 一 个 fdisk 分 区 表 中 , 但 可 见 于 /dev/sda* 或 /dev/hda* 中 。<br />

# fdisk /dev/sda # 查 找 FreeBSD 分 区<br />

/dev/sda3 * 5357 7905 20474842+ a5 FreeBSD<br />

# mount -t ufs -o ufstype=ufs2,ro /dev/sda3 /mnt<br />

/dev/sda10 = /tmp; /dev/sda11 /usr # 其 他 slice<br />

重 挂 载<br />

不 用 卸 载 一 个 设 备 来 重 挂 载 。 对 fsck 来 说 是 必 须 的 。 举 个 例 子 :<br />

# mount -o remount,ro / # Linux<br />

# mount -o ro / # FreeBSD<br />

10


从 cdrom 拷 贝 原 始 数 据 进 一 个 iso 映 像 文 件 :<br />

# dd if=/dev/cd0c of=file.iso<br />

3.7 给 即 时 烧 录 (on-the-fly) 添 加 swap<br />

假 设 你 需 要 很 多 的 swap ( 即 刻 ), 如 一 个 2GB 文 件 /swap2gb ( 只 限 Linux)。<br />

# dd if=/dev/zero of=/swap2gb bs=1024k count=2000<br />

# mkswap /swap2gb # 创 建 交 换 区<br />

# swapon /swap2gb # 激 活 这 个 swap。 现 在 可 以 使 用 了<br />

# swapoff /swap2gb # 当 使 用 完 毕 , 释 放 这 个 swap<br />

# rm /swap2gb<br />

3.8 挂 载 一 个 SMB 14 共 享<br />

假 设 我 们 要 访 问 计 算 机 smbserver 上 的 名 叫 myshare 的 SMB 共 享 , 在 window PC 上 键 入 的 地 址 是<br />

\\smbserver\myshare\。 我 挂 载 到 /mnt/smbshare 上 。 注 意 cifs 必 须 是 IP 或 DNS 名 , 不 是 Windows 名<br />

字 。<br />

Linux<br />

# smbclient -U user -I 192.168.16.229 -L //smbshare/ # 列 出 共 享<br />

# mount -t smbfs -o username=winuser //smbserver/myshare /mnt/smbshare<br />

# mount -t cifs -o username=winuser,password=winpwd //192.168.16.229/myshare /mnt/share<br />

此 外 ,mount.cifs 软 件 包 可 以 存 储 认 证 到 一 个 文 件 中 。 例 如 ,/home/user/.smb:<br />

username=winuser<br />

password=winpwd<br />

现 在 可 以 像 下 面 那 样 挂 载 :<br />

# mount -t cifs -o credentials=/home/user/.smb //192.168.16.229/myshare /mnt/smbshare<br />

FreeBSD<br />

使 用 -I 来 获 取 IP ( 或 DNS 名 );smbserver 是 Windows 名 。<br />

# smbutil view -I 192.168.16.229 //winuser@smbserver # 列 出 共 享<br />

# mount_smbfs -I 192.168.16.229 //winuser@smbserver/myshare /mnt/smbshare<br />

3.9 挂 载 镜 像 文 件<br />

Linux loop-back<br />

# mount -t iso9660 -o loop file.iso /mnt # 挂 载 CD 镜 像 文 件<br />

# mount -t ext3 -o loop file.img /mnt # 用 ext3 文 件 系 统 挂 载 镜 像 文 件<br />

FreeBSD<br />

用 于 存 储 设 备 ( 如 果 需 要 做 # kldload md.ko 动 作 ):<br />

# mdconfig -a -t vnode -f file.iso -u 0<br />

# mount -t cd9660 /dev/md0 /mnt<br />

# umount /mnt; mdconfig -d -u 0 # 清 除 md 设 备<br />

用 于 虚 拟 节 点 :<br />

— 文 件 系 统 —<br />

# vnconfig /dev/vn0c file.iso; mount -t cd9660 /dev/vn0c /mnt<br />

# umount /mnt; vnconfig -u /dev/vn0c # 清 除 vn 设 备<br />

14. 译 注 :SMB (Server Message Block, 服 务 器 信 息 块 ), 又 称 CIFS (Common Internet File<br />

System, 通 用 Internet 文 件 系 统 )<br />

11


— 文 件 系 统 —<br />

Solaris and FreeBSD<br />

用 于 loop-back 文 件 接 口 或 lofi:<br />

# lofiadm -a file.iso<br />

# mount -F hsfs -o ro /dev/lofi/1 /mnt<br />

# umount /mnt; lofiadm -d /dev/lofi/1 # 清 除 lofi 设 备<br />

3.10 创 建 并 刻 录 ISO 镜 像 文 件<br />

这 将 会 拷 贝 CD 或 者 DVD 的 扇 区 。 当 不 用 conv=notrunc, 镜 像 文 件 会 等 于 CD 内 容 大 小 而 非 CD 容 量 大 小 。 看<br />

下 面 和 dd 例 子 (page 39)。<br />

# dd if=/dev/hdc of=/tmp/mycd.iso bs=2048 conv=notrunc<br />

使 用 mkisofs 把 目 录 中 所 有 文 件 创 建 成 CD/DVD 镜 像 文 件 。 克 服 文 件 名 限 制 :-r 开 启 Rock Ridge 扩 展 用 于<br />

<strong>Unix</strong> 系 统 ,-J 开 启 Joliet 扩 展 用 于 微 软 系 统 。-L 允 许 ISO9660 文 件 名 第 一 个 字 符 为 句 点 。<br />

# mkisofs -J -L -r -V TITLE -o imagefile.iso /path/to/dir<br />

对 于 FreeBSD,mkisofs 可 以 到 port 的 sysutils/cdrtools 中 找 到 。<br />

刻 录 ISO 镜 像 文 件<br />

FreeBSD<br />

FreeBSD 默 认 情 况 下 没 有 在 ATAPI 驱 动 上 启 用 DMA。DMA 可 用 sysctl 命 令 启 用 , 其 参 数 如 下 , 或 者 在 /boot/<br />

loader.conf 中 添 加 如 下 条 目 :<br />

hw.ata.ata_dma="1"<br />

hw.ata.atapi_dma="1"<br />

burncd 用 于 ATAPI 驱 动 (burncd 为 基 本 系 统 的 一 部 分 ),cdrecord ( 在 sysutils/cdrtools 中 ) 用 于 SCSI 驱<br />

动 。<br />

# burncd -f /dev/acd0 data imagefile.iso fixate # ATAPI 驱 动<br />

# cdrecord -scanbus # 查 找 burner 设 备 描 述 符 ( 如 1,0,0)<br />

# cdrecord dev=1,0,0 imagefile.iso<br />

Linux<br />

对 于 Linux, 同 样 使 用 cdrecord 如 上 文 所 述 。 此 外 , 它 还 可 以 使 用 本 地 ATAPI 接 口 查 找 设 备 描 述 符 :<br />

# cdrecord dev=ATAPI -scanbus<br />

然 后 同 上 面 一 样 烧 录 CD/DVD。<br />

dvd+rw-tools<br />

dvd+rw-tools 15 工 具 包 (FreeBSD: ports/sysutils/dvd+rw-tools) 可 以 做 上 面 的 一 切 , 其 还 包 括 growisofs 工<br />

具 来 刻 录 CD 或 DVD。 本 实 例 所 引 用 的 DVD 设 备 /dev/dvd 可 能 是 指 向 /dev/scd0 (Linux) 的 符 号 连 接 , 或 者<br />

/dev/cd0 (FreeBSD), 或 者 /dev/rcd0c (NetBSD/OpenBSD), 或 者 /dev/rdsk/c0t1d0s2 (Solaris)。 对 于 本 实<br />

16<br />

例 FreeBSD 手 册 18.7 章 上 有 一 份 很 好 的 文 档 。<br />

# -dvd-compat 选 项 将 完 结 光 盘 , 光 盘 便 不 可 再 附 加 数 据<br />

# growisofs -dvd-compat -Z /dev/dvd=imagefile.iso # 刻 录 已 存 在 的 iso 镜 像 文 件<br />

# growisofs -dvd-compat -Z /dev/dvd -J -R /p/to/data # 直 接 刻 录<br />

转 换 Nero .nrg 文 件 成 .iso<br />

Nero 简 单 的 添 加 了 300KB 的 头 到 一 个 常 规 的 iso 镜 像 文 件 中 。 我 们 可 用 dd 工 具 来 去 除 它 。<br />

# dd bs=1k if=imagefile.nrg of=imagefile.iso skip=300<br />

转 换 bin/cue 镜 像 成 .iso<br />

bchunk 程 序<br />

17<br />

可 以 做 到 这 一 点 。 在 FreeBSD 中 , 它 在 port 的 sysutils/bchunk 中 。<br />

15.http://fy.chalmers.se/~appro/linux/DVD+RW/<br />

16.http://www.freebsd.org/handbook/creating-dvds.html<br />

12


# bchunk imagefile.bin imagefile.cue imagefile.iso<br />

— 文 件 系 统 —<br />

3.11 创 建 基 于 文 件 的 镜 像 文 件<br />

举 个 例 子 , 一 个 使 用 文 件 /usr/vdisk.img 的 1GB 分 区 。 这 里 我 们 使 用 vnode 0, 但 也 可 为 1。<br />

FreeBSD<br />

# dd if=/dev/random of=/usr/vdisk.img bs=1K count=1M<br />

# mdconfig -a -t vnode -f /usr/vdisk.img -u 0 # 创 建 设 备 /dev/md1<br />

# bsdlabel -w /dev/md0<br />

# newfs /dev/md0c<br />

# mount /dev/md0c /mnt<br />

# umount /mnt; mdconfig -d -u 0; rm /usr/vdisk.img # 清 除 md 设 备<br />

这 个 基 于 文 件 的 镜 像 文 件 可 以 在 /etc/rc.conf 和 /etc/fstab 中 配 置 成 启 动 期 间 自 动 挂 载 。 可 用 # /etc/<br />

rc.d/mdconfig start ( 先 用 # mdconfig -d -u 0 命 令 删 除 md0 设 备 ) 测 试 你 的 设 置 。<br />

需 要 注 意 的 是 , 那 个 自 动 设 置 仅 工 作 于 这 个 基 于 文 件 的 镜 像 文 件 不 在 root 分 区 中 。 原 因 是 /etc/rc.d/<br />

mdconfig 脚 本 早 于 启 动 就 执 行 了 , 并 且 root 分 区 仍 然 是 只 读 的 。 脚 本 /etc/rc.d/mdconfig2 之 后 , 镜 像 文 件<br />

将 位 于 root 分 区 外 挂 载 。<br />

/boot/loader.conf:<br />

md_load="YES"<br />

/etc/rc.conf:<br />

# mdconfig_md0="-t vnode -f /usr/vdisk.img" # /usr 不 在 root 分 区 中<br />

/etc/fstab: ( 行 后 的 两 个 0 0 很 重 要 , 它 告 诉 fsck 忽 略 这 个 设 备 , 现 在 还 不 存 在 。)<br />

/dev/md0 /usr/vdisk ufs rw 0 0<br />

也 可 能 在 增 加 镜 像 文 件 的 大 小 之 后 , 如 增 大 到 300MB。<br />

# umount /mnt; mdconfig -d -u 0<br />

# dd if=/dev/zero bs=1m count=300 >> /usr/vdisk.img<br />

# mdconfig -a -t vnode -f /usr/vdisk.img -u 0<br />

# growfs /dev/md0<br />

# mount /dev/md0c /mnt # 文 件 分 区 现 在 为 300MB<br />

Linux<br />

# dd if=/dev/zero of=/usr/vdisk.img bs=1024k count=1024<br />

# mkfs.ext3 /usr/vdisk.img<br />

# mount -o loop /usr/vdisk.img /mnt<br />

# umount /mnt; rm /usr/vdisk.img # 清 楚<br />

Linux with losetup<br />

/dev/zero 比 urandom 更 快 , 但 对 于 加 密 来 说 却 不 够 安 全 。<br />

# dd if=/dev/urandom of=/usr/vdisk.img bs=1024k count=1024<br />

# losetup /dev/loop0 /usr/vdisk.img # 创 建 并 联 结 /dev/loop0<br />

# mkfs.ext3 /dev/loop0<br />

# mount /dev/loop0 /mnt<br />

# losetup -a # 查 看 已 经 挂 载 的 loop 设 备<br />

# umount /mnt<br />

# losetup -d /dev/loop0 # Detach<br />

# rm /usr/vdisk.img<br />

3.12 创 建 基 于 内 存 的 文 件 系 统<br />

基 于 内 存 的 文 件 系 统 对 于 重 量 级 IO 应 用 程 序 来 说 非 常 快 。 怎 样 创 建 一 个 挂 载 到 /memdisk 的 64M 分 区 :<br />

17.http://freshmeat.net/projects/bchunk/<br />

13


— 网 络 —<br />

FreeBSD<br />

# mount_mfs -o rw -s 64M md /memdisk<br />

# umount /memdisk; mdconfig -d -u 0 # 清 除 该 md 设 备<br />

md /memdisk mfs rw,-s64M 0 0 # /etc/fstab 条 目<br />

Linux<br />

# mount -t tmpfs -osize=64m tmpfs /memdisk<br />

3.13 磁 盘 性 能<br />

在 ad4s3c (/home) 分 区 上 读 写 一 个 1GB 的 文 件 。<br />

# time dd if=/dev/ad4s3c of=/dev/null bs=1024k count=1000<br />

# time dd if=/dev/zero bs=1024k count=1000 of=/home/1Gb.file<br />

# hdparm -tT /dev/hda # 仅 限 Linux<br />

4 网 络<br />

路 由 (p14) | 额 外 IP (p15) | 更 改 MAC 地 址 (p16) | 端 口 (p16) | 防 火 墙 (p16) | IP 转 发 (p16) | NAT<br />

(p17) | DNS (p17) | DHCP (p18) | 通 信 量 (p19) | QoS (p20) | NIS (p21)<br />

4.1 调 试 ( 也 可 看 流 量 分 析 ) (page 19)<br />

Linux<br />

# ethtool eth0 # 显 示 以 太 网 状 态 (replaces mii-diag)<br />

# ethtool -s eth0 speed 100 duplex full # 把 网 卡 eth0 速 度 改 为 100 兆 / 秒 , 采 用 全 双 工<br />

# ethtool -s eth0 autoneg off # 禁 用 自 动 协 商 模 式<br />

# ethtool -p eth1 # 闪 烁 网 络 接 口 LED 灯 - 如 果 支 持 的 话 , 非 常 实 用<br />

# ip link show # 在 Linux 上 显 示 所 有 网 络 接 口 ( 同 ifconfig 类 似 )<br />

# ip link set eth0 up # 使 设 备 激 活 ( 或 Down 掉 )。 同 "ifconfig eth0 up"<br />

# ip addr show # 在 Linux 上 显 示 所 有 IP 地 址 ( 与 ifconfig 类 似 )<br />

# ip neigh show # 与 arp -a 类 似<br />

其 他 系 统<br />

# ifconfig fxp0 # 查 看 "media" 字 段 (FreeBSD)<br />

# arp -a # 查 看 路 由 ( 或 主 机 ) ARP 条 目 ( 所 有 系 统 )<br />

# ping cb.vu # 第 一 个 要 试 的 事 情 ...<br />

# traceroute cb.vu # 列 印 到 目 的 地 的 路 由 路 径<br />

# ifconfig fxp0 media 100baseTX mediaopt full-duplex # 100 兆 / 秒 全 双 工 (FreeBSD)<br />

# netstat -s # 对 每 个 网 络 协 议 做 系 统 级 分 析<br />

另 一 些 命 令 , 虽 然 不 总 是 默 认 安 装 , 但 很 好 找 :<br />

# arping 192.168.16.254 # 在 网 络 层 上 Ping<br />

# tcptraceroute -f 5 cb.vu # 使 用 tcp 替 换 icmp 来 跟 踪 , 透 过 防 火 墙<br />

4.2 路 由<br />

列 印 路 由 表<br />

# route -n # Linux 或 使 用 "ip route"<br />

# netstat -rn # Linux, BSD 和 UNIX<br />

# route print # Windows<br />

14


— 网 络 —<br />

添 加 删 除 路 由<br />

FreeBSD<br />

# route add 212.117.0.0/16 192.168.1.1<br />

# route delete 212.117.0.0/16<br />

# route add default 192.168.1.1<br />

永 久 的 添 加 路 由 可 在 /etc/rc.conf 配 置 文 件 中 设 置<br />

static_routes="myroute"<br />

route_myroute="-net 212.117.0.0/16 192.168.1.1"<br />

Linux<br />

# route add -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.16.254<br />

# ip route add 192.168.20.0/24 via 192.168.16.254 # 等 同 于 上 面 命 令<br />

# route add -net 192.168.20.0 netmask 255.255.255.0 dev eth0<br />

# route add default gw 192.168.51.254<br />

# ip route add default via 192.168.51.254 dev eth0 # 等 同 于 上 面 命 令<br />

# route delete -net 192.168.20.0 netmask 255.255.255.0<br />

Solaris<br />

# route add -net 192.168.20.0 -netmask 255.255.255.0 192.168.16.254<br />

# route add default 192.168.51.254 1 # 1 = 通 过 此 路 由 跳<br />

18<br />

数 减 1<br />

# route change default 192.168.50.254 1<br />

永 久 条 目 配 置 在 /etc/defaultrouter 中 。<br />

Windows<br />

# Route add 192.168.50.0 mask 255.255.255.0 192.168.51.253<br />

# Route add 0.0.0.0 mask 0.0.0.0 192.168.51.254<br />

使 用 add -p 来 是 路 由 设 置 永 久 有 效 。<br />

4.3 配 置 额 外 的 IP 地 址<br />

Linux<br />

# ifconfig eth0 192.168.50.254 netmask 255.255.255.0 # 第 一 个 IP<br />

# ifconfig eth0:0 192.168.51.254 netmask 255.255.255.0 # 第 二 个 IP<br />

# ip addr add 192.168.50.254/24 dev eth0 # 等 价 命 令<br />

# ip addr add 192.168.51.254/24 dev eth0 label eth0:1<br />

FreeBSD<br />

# ifconfig fxp0 inet 192.168.50.254/24 # 第 一 个 IP<br />

# ifconfig fxp0 alias 192.168.51.254 netmask 255.255.255.0 # 第 二 个 IP<br />

永 久 条 目 设 置 在 /etc/rc.conf 中<br />

ifconfig_fxp0="inet 192.168.50.254 netmask 255.255.255.0"<br />

ifconfig_fxp0_alias0="192.168.51.254 netmask 255.255.255.0"<br />

Solaris<br />

用 ifconfig -a 命 令 检 查 设 置<br />

# ifconfig hme0 plumb # 启 用 网 卡<br />

# ifconfig hme0 192.168.50.254 netmask 255.255.255.0 up # 第 一 个 IP<br />

# ifconfig hme0:1 192.168.51.254 netmask 255.255.255.0 up # 第 二 个 IP<br />

18. 译 注 : 数 据 包 生 存 周 期 依 赖 于 IP 头 中 的 生 存 周 期 (Time-to-Live, 简 称 TTL)。 根 据 RFC 的 定 义 , 这 个 域 值 由 每 个 路 由 器 来 减 少 。 接 收 到 包 的 每 台 路 由 器 根 据 路 由 该<br />

15


— 网 络 —<br />

4.4 更 改 MAC 地 址<br />

通 常 在 你 更 改 之 前 先 停 下 网 络 接 口 。 不 要 告 诉 我 为 什 么 你 想 改 变 MAC 地 址 ......<br />

# ifconfig eth0 down<br />

# ifconfig eth0 hw ether 00:01:02:03:04:05 # Linux<br />

# ifconfig fxp0 link 00:01:02:03:04:05 # FreeBSD<br />

# ifconfig hme0 ether 00:01:02:03:04:05 # Solaris<br />

# sudo ifconfig en0 ether 00:01:02:03:04:05 # Mac OS X Tiger<br />

# sudo ifconfig en0 lladdr 00:01:02:03:04:05 # Mac OS X Leopard<br />

对 于 Windows 已 经 有 许 多 工 具 了 。 像 etherchange 19 。 或 者 看 看 "Mac Makeup", "smac"。<br />

4.5 使 用 中 的 端 口<br />

监 听 打 开 的 端 口 :<br />

# netstat -an | grep LISTEN<br />

# lsof -i # 列 出 所 有 因 特 网 连 接 (Linux)<br />

# socklist # 列 出 打 开 的 socket (Linux)<br />

# sockstat -4 # 使 用 socket 的 应 用 程 序 列 表 (FreeBSD)<br />

# netstat -anp --udp --tcp | grep LISTEN # Linux<br />

# netstat -tup # 列 出 活 跃 的 连 接 (Linux)<br />

# netstat -tupl # 列 出 系 统 中 正 在 监 听 的 端 口 (Linux)<br />

# netstat -ano # Windows<br />

4.6 防 火 墙<br />

检 查 正 在 运 行 的 防 火 墙 ( 只 是 典 型 配 置 ):<br />

Linux<br />

# iptables -L -n -v # 状 态 信 息<br />

Open the iptables firewall<br />

# iptables -P INPUT ACCEPT # 打 开 所 有<br />

# iptables -P FORWARD ACCEPT<br />

# iptables -P OUTPUT ACCEPT<br />

# iptables -Z # 把 所 有 链 的 包 及 字 节 的 计 数 器 清 空<br />

# iptables -F # 清 空 所 有 链<br />

# iptables -X<br />

20<br />

# 删 除 所 有 链<br />

FreeBSD<br />

# ipfw show # 状 态 信 息<br />

# ipfw list 65535 # 如 果 显 示 "65535 deny ip from any to any", 那 防 火 墙 已 被 禁 用<br />

# sysctl net.inet.ip.fw.enable=0 # 禁 用<br />

# sysctl net.inet.ip.fw.enable=1 # 启 用<br />

4.7 路 由 IP 转 发<br />

Linux<br />

查 看 然 后 启 用 IP 转 发 :<br />

# cat /proc/sys/net/ipv4/ip_forward # 查 看 IP 转 发 0= 禁 用 , 1= 启 用<br />

# echo 1 > /proc/sys/net/ipv4/ip_forward<br />

或 者 编 辑 /etc/sysctl.conf:<br />

net.ipv4.ip_forward = 1<br />

19.http://ntsecurity.nu/toolbox/etherchange<br />

20. 译 注 : 链 必 须 没 有 被 引 用<br />

16


— 网 络 —<br />

FreeBSD<br />

查 看 并 启 用 :<br />

# sysctl net.inet.ip.forwarding # 查 看 IP 转 发 0= 禁 用 , 1= 启 用<br />

# sysctl net.inet.ip.forwarding=1<br />

# sysctl net.inet.ip.fastforwarding=1 # 专 用 路 由 器 或 防 火 墙<br />

Permanent with entry in /etc/rc.conf:<br />

gateway_enable="YES"<br />

# 如 果 主 机 是 网 关 则 设 置 为 YES。<br />

Solaris<br />

# ndd -set /dev/ip ip_forwarding 1 # 查 看 IP 转 发 0= 禁 用 , 1= 启 用<br />

4.8 NAT - 网 络 地 址 转 换<br />

Linux<br />

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # 激 活 NAT<br />

# iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 20022 -j DNAT \<br />

--to 192.168.16.44:22<br />

# 转 发 端 口 20022 到 内 部 IP 端 口 (ssh)<br />

# iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 993:995 -j DNAT \<br />

--to 192.168.16.254:993:995 # 转 发 993-995 范 围 端 口<br />

# ip route flush cache<br />

# iptables -L -t nat # 查 看 NAT 状 态 信 息<br />

使 用 -D 替 换 -A 来 删 除 端 口 转 发 。<br />

FreeBSD<br />

# natd -s -m -u -dynamic -f /etc/natd.conf -n fxp0<br />

Or edit /etc/rc.conf with:<br />

firewall_enable="YES"<br />

# 设 置 YES 来 启 用 防 火 墙 功 能<br />

firewall_type="open"<br />

# 防 火 墙 类 型 ( 看 /etc/rc.firewall)<br />

natd_enable="YES"<br />

# 启 用 natd ( 如 果 firewall_enable == YES)。<br />

natd_interface="tun0" # 公 共 的 网 络 接 口 或 要 使 用 的 IP 地 址 。<br />

natd_flags="-s -m -u -dynamic -f /etc/natd.conf"<br />

端 口 转 发 :<br />

# cat /etc/natd.conf<br />

same_ports yes<br />

use_sockets yes<br />

unregistered_only<br />

# redirect_port tcp insideIP:2300-2399 3300-3399 # 端 口 范 围<br />

redirect_port udp 192.168.51.103:7777 7777<br />

4.9 DNS<br />

在 unix 上 , 对 于 所 有 的 网 络 接 口 的 DNS 条 目 都 存 储 在 /etc/resolv.conf 文 件 中 。 主 机 域 也 储 存 在 这 个 文 件<br />

中 。 最 小 化 配 置 如 下 :<br />

nameserver 78.31.70.238<br />

search sleepyowl.net intern.lab<br />

domain sleepyowl.net<br />

检 查 系 统 域 名 :<br />

# hostname -d # 等 同 于 dnsdomainname<br />

Windows<br />

在 Windows 上 ,DNS 配 置 于 每 个 网 络 接 口 。 要 显 示 配 置 的 DNS 和 清 空 DNS 缓 存 可 是 使 用 :<br />

17


# ipconfig /? # 显 示 帮 助<br />

# ipconfig /all # 显 示 所 有 信 息 包 括 DNS<br />

# ipconfig /flushdns # 清 除 DNS 缓 存<br />

转 发 查 询<br />

Dig 是 你 测 试 DNS 设 置 的 好 朋 友 。 举 个 例 子 , 用 于 测 试 的 DNS 服 务 器 为 213.133.105.2 ns.second-ns.de。 查<br />

看 哪 个 服 务 器 客 户 端 接 收 应 答 ( 简 单 应 答 ).<br />

# dig sleepyowl.net<br />

sleepyowl.net. 600 IN A 78.31.70.238<br />

;; SERVER: 192.168.51.254#53(192.168.51.254)<br />

路 由 器 192.168.51.254 应 答 了 , 并 返 回 了 一 条 A 条 目 ( 记 录 )。 任 何 条 目 都 可 查 询 ,DNS 服 务 器 可 用 @ 来 选<br />

定 :<br />

# dig MX google.com<br />

# dig @127.0.0.1 NS sun.com # 测 试 本 地 服 务 器<br />

# dig @204.97.212.10 NS MX heise.de # 查 询 外 部<br />

# dig AXFR @ns1.xname.org cb.vu # 查 看 区 传 送 (zone transfer)<br />

程 式 host 也 很 强 大 。<br />

# host -t MX cb.vu # 获 取 邮 件 MX 记 录<br />

# host -t NS -T sun.com # 通 过 TCP 连 接 获 取 NS 记 录<br />

# host -a sleepyowl.net # 获 取 所 有<br />

反 向 查 询<br />

查 找 属 于 一 个 IP 地 址 (in-addr.arpa.) 的 域 名 。 可 用 dig, host 和 nslookup 命 令 查 询 :<br />

# dig -x 78.31.70.238<br />

# host 78.31.70.238<br />

# nslookup 78.31.70.238<br />

/etc/hosts<br />

单 个 主 机 可 以 配 置 于 文 件 /etc/hosts 来 代 替 本 地 正 在 运 行 的 named 反 向 域 名 查 询 。 格 式 很 简 单 , 举 个 例 子 :<br />

78.31.70.238 sleepyowl.net sleepyowl<br />

对 于 hosts 文 件 和 DNS 查 询 之 间 的 优 先 级 , 可 在 /etc/nsswitch.conf 和 /etc/host.conf 中 配 置 order 名<br />

称 解 析 。 这 个 文 件 同 样 存 在 于 Windows 上 , 通 常 在 :<br />

C:\WINDOWS\SYSTEM32\DRIVERS\ETC<br />

4.10 DHCP<br />

Linux<br />

一 些 发 行 版 (SuSE) 使 用 dhcpcd 作 为 客 户 端 。 默 认 网 络 接 口 是 eth0。<br />

# dhcpcd -n eth0 # 触 发 更 新 ( 并 不 总 是 可 以 工 作 )<br />

# dhcpcd -k eth0 # 释 放 并 关 闭<br />

租 约 (lease) 的 全 部 信 息 存 储 在 :<br />

/var/lib/dhcpcd/dhcpcd-eth0.info<br />

FreeBSD<br />

FreeBSD ( 和 Debian) 使 用 dhclient。 要 配 置 一 个 网 络 接 口 ( 如 :bge0) 运 行 :<br />

# dhclient bge0<br />

租 约 (lease) 的 全 部 信 息 存 储 在 :<br />

/var/db/dhclient.leases.bge0<br />

— 网 络 —<br />

18


— 网 络 —<br />

使 用<br />

/etc/dhclient.conf<br />

设 置 prepend 选 项 或 强 制 不 同 的 选 项 :<br />

# cat /etc/dhclient.conf<br />

interface "rl0" {<br />

prepend domain-name-servers 127.0.0.1;<br />

default domain-name "sleepyowl.net";<br />

supersede domain-name "sleepyowl.net";<br />

}<br />

Windows<br />

dhcp 租 约 (lease) 使 用 ipconfig 来 更 新 :<br />

# ipconfig /renew # 更 新 所 有 适 配 器<br />

# ipconfig /renew LAN # 更 新 名 叫 "LAN" 的 适 配 器<br />

# ipconfig /release WLAN # 释 放 名 叫 "WLAN" 的 适 配 器<br />

是 的 , 这 是 一 个 使 用 简 单 名 称 重 新 命 名 你 的 适 配 器 的 好 主 意 !<br />

4.11 通 信 量 分 析 (Traffic analysis)<br />

Bmon 21 是 一 个 小 的 流 量 监 控 控 制 台 , 而 且 可 以 显 示 不 同 的 网 络 接 口 的 流 量 。<br />

用 tcpdump 嗅 探 (sniff)<br />

# tcpdump -nl -i bge0 not port ssh and src \(192.168.16.121 or 192.168.16.54\)<br />

# tcpdump -l > dump && tail -f dump # 缓 冲 输 出<br />

# tcpdump -i rl0 -w traffic.rl0 # 把 数 据 报 文 写 入 二 进 制 文 件<br />

# tcpdump -r traffic.rl0 # 从 文 件 读 取 数 据 报 文 ( 也 可 以 使 用 ethereal)<br />

# tcpdump port 80 # 两 个 经 典 命 令<br />

# tcpdump host google.com<br />

# tcpdump -i eth0 -X port \(110 or 143\) # 查 看 端 口 110(POP) 或 143(IMAP) 的 数 据 报 文<br />

# tcpdump -n -i eth0 icmp # 只 捕 获 ping<br />

# tcpdump -i eth0 -s 0 -A port 80 | grep GET # -s 0 为 全 部 包 , -A 为 ASCII<br />

另 一 些 重 要 选 项 :<br />

-A 显 示 每 个 包 清 晰 文 本 ( 除 了 报 头 )<br />

-X 显 示 包 的 ASCII 文 本<br />

-l 使 标 准 输 出 变 为 缓 冲 行 形 式<br />

-D 显 示 所 有 可 用 网 络 接 口<br />

对 于 Windows 可 以 使 用 www.winpcap.org。 使 用 windump -D 来 列 出 网 络 接 口 。<br />

用 nmap 扫 描<br />

Nmap 22 是 一 个 用 于 OS 探 测 的 端 口 扫 描 工 具 , 她 通 常 在 许 多 发 行 版 上 有 安 装 , 并 且 同 样 可 用 于 Windows。 如 果 你<br />

不 扫 描 你 的 服 务 器 , 骇 客 们 会 为 你 做 这 些 ...<br />

# nmap cb.vu # 扫 描 主 机 上 所 有 保 留 的 TCP 端 口<br />

# nmap -sP 192.168.16.0/24 # 找 出 在 0/24 上 主 机 所 使 用 的 IP 23<br />

# nmap -sS -sV -O cb.vu # 做 秘 密 SYN 扫 描 来 探 测 系 统 和 系 统 服 务 的 版 本 信 息<br />

PORT STATE SERVICE VERSION<br />

22/tcp open ssh OpenSSH 3.8.1p1 FreeBSD-20060930 (protocol 2.0)<br />

25/tcp open smtp Sendmail smtpd 8.13.6/8.13.6<br />

80/tcp open http Apache httpd 2.0.59 ((FreeBSD) DAV/2 PHP/4.<br />

[...]<br />

Running: FreeBSD 5.X<br />

Uptime 33.120 days (since Fri Aug 31 11:41:04 2007)<br />

21.http://people.suug.ch/~tgr/bmon/<br />

22.http://insecure.org/nmap/<br />

23. 译 注 : 通 过 使 用 "-sP" 参 数 , 进 行 ping 扫 描 。 缺 省 情 况 下 ,Nmap 给 每 个 扫 描 到 的 主 机 发 送 一 个 ICMP echo 和 一 个 TCP ACK, 主 机 对 任 何 一 种 的 响 应 都 会 被 Nmap 得<br />

19


其 他 非 标 准 但 好 用 的 工 具 有 hping (www.hping.org), 她 是 一 个 IP 分 组 组 装 / 分 析 器 , 和 fping<br />

(fping.sourceforge.net)。fping 可 以 在 一 个 循 环 队 列 (round-robin fashion) 中 扫 描 多 种 主 机 。<br />

4.12 流 量 控 制 (QoS)<br />

— 网 络 —<br />

流 量 控 制 管 理 着 一 个 网 络 的 队 列 、 流 量 监 控 、 调 度 以 及 其 他 流 量 设 置 (traffic<br />

例 使 用 Linux 和 FreeBSD 的 能 力 来 更 好 的 利 用 带 宽 。<br />

parameters)。 以 下 简 单 实 用 的 示<br />

上 传 限 制<br />

DSL 或 有 线 调 制 解 调 器 有 一 个 很 长 的 列 队 来 提 高 上 传 吞 吐 量 (upload throughput)。 然 而 用 一 个 快 速 的 设 备 ( 如 以<br />

太 网 ) 填 充 这 个 列 队 将 大 大 减 少 交 互 性 。 这 就 是 限 制 设 备 上 传 速 度 有 用 的 原 因 , 以 匹 配 调 制 解 调 器 的 实 际 能 力 ,<br />

这 可 以 有 效 提 高 交 互 性 。 设 置 大 约 为 modem 最 大 速 度 的 90%。<br />

Linux<br />

给 512K 上 传 速 度 的 modem。<br />

# tc qdisc add dev eth0 root tbf rate 480kbit latency 50ms burst 1540<br />

# tc -s qdisc ls dev eth0 # 状 态<br />

# tc qdisc del dev eth0 root # 删 除 队 列<br />

# tc qdisc change dev eth0 root tbf rate 220kbit latency 50ms burst 1540<br />

FreeBSD<br />

FreeBSD 使 用 dummynet 来 控 制 带 宽 , 其 配 置 工 具 为 ipfw。Pipe 用 来 设 置 限 制 带 宽 的 单 位 [K|M]{ 比 特 / 秒 | 字 节<br />

/ 秒 },0 意 味 着 没 有 限 制 。 使 用 同 样 的 pipe 数 字 可 重 新 配 置 它 。 举 个 例 子 , 限 制 上 传 带 宽 为 500K。<br />

# kldload dummynet # 如 有 必 要 加 载 这 个 模 块<br />

# ipfw pipe 1 config bw 500Kbit/s # 创 建 一 个 带 宽 限 制 的 pipe<br />

# ipfw add pipe 1 ip from me to any # 转 移 所 有 上 传 进 入 这 个 pipe<br />

服 务 质 量 (Quality of service)<br />

Linux<br />

使 用 tc 的 优 先 级 队 列 来 优 化 VoIP。 在 voip-info.org 或 www.howtoforge.com 上 可 以 看 到 完 整 的 例 子 。 假 设<br />

VoIP 使 用 UDP 端 口 10000:11024 并 且 使 用 eth0 设 备 ( 也 可 为 ppp0 或 so)。 下 列 命 令 定 义 了 三 个 队 列 , 并 且<br />

用 QoS 0x1e( 设 置 所 有 位 ) 强 制 VOIP 流 量 到 队 列 1。 默 认 流 量 流 入 队 列 3,Qos Minimize-Delay 流 入 队 列<br />

2。<br />

# tc qdisc add dev eth0 root handle 1: prio priomap 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 0<br />

# tc qdisc add dev eth0 parent 1:1 handle 10: sfq<br />

# tc qdisc add dev eth0 parent 1:2 handle 20: sfq<br />

# tc qdisc add dev eth0 parent 1:3 handle 30: sfq<br />

# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 \<br />

match ip dport 10000 0x3C00 flowid 1:1 # 使 用 服 务 端 端 口 范 围<br />

match ip dst 123.23.0.1 flowid 1:1<br />

# 或 / 和 使 用 服 务 器 IP<br />

状 态 和 移 除 :<br />

# tc -s qdisc ls dev eth0 # queue status<br />

# tc qdisc del dev eth0 root # delete all QoS<br />

计 算 端 口 范 围 和 掩 码 (mask)<br />

用 你 所 计 算 的 端 口 掩 码 来 定 义 tc 过 滤 器 的 端 口 范 围 。 查 询 2^N 端 口 范 围 结 尾 , 推 断 范 围 并 转 换 成 十 六 进 制 。<br />

这 就 是 你 的 掩 码 (mask)。 例 如 10000 -> 11024, 它 的 范 围 是 1024。<br />

# 2^13 (8192) < 10000 < 2^14 (16384) # 结 尾 是 2^14 = 16384<br />

# echo "obase=16;(2^14)-1024" | bc # 掩 码 是 0x3C00<br />

FreeBSD<br />

假 设 最 大 连 接 带 宽 为 500Kbit/s, 我 们 使 用 优 先 级 100:10:1 定 义 3 个 队 列 给 VoIP:ssh: 剩 余 所 有 。<br />

# ipfw pipe 1 config bw 500Kbit/s<br />

# ipfw queue 1 config pipe 1 weight 100<br />

20


# ipfw queue 2 config pipe 1 weight 10<br />

# ipfw queue 3 config pipe 1 weight 1<br />

# ipfw add 10 queue 1 proto udp dst-port 10000-11024<br />

# ipfw add 11 queue 1 proto udp dst-ip 123.23.0.1 # 或 / 和 使 用 服 务 器 IP<br />

# ipfw add 20 queue 2 dsp-port ssh<br />

# ipfw add 30 queue 3 from me to any # 剩 余 所 有<br />

状 态 和 移 除 :<br />

— SSH SCP —<br />

# ipfw list # 规 则 信 息<br />

# ipfw pipe list # 管 道 信 息<br />

# ipfw flush # 删 除 除 默 认 外 所 有 规 则<br />

4.13 NIS 调 试<br />

一 些 可 工 作 在 已 配 置 好 的 NIS 客 户 端 上 的 命 令 :<br />

# ypwhich # 获 取 提 供 NIS 服 务 的 服 务 器 名<br />

# domainname # 已 配 置 的 NIS 域 名<br />

# ypcat group # 列 印 NIS 映 射 group<br />

# cd /var/yp && make # 重 建 yp 数 据 库<br />

ypbind 正 在 运 行 吗 ?<br />

# ps auxww | grep ypbind<br />

/usr/sbin/ypbind -s -m -S servername1,servername2 # FreeBSD<br />

/usr/sbin/ypbind<br />

# Linux<br />

# yppoll passwd.byname<br />

Map passwd.byname has order number 1190635041. Mon Sep 24 13:57:21 2007<br />

The master server is servername.domain.net.<br />

Linux<br />

# cat /etc/yp.conf<br />

ypserver servername<br />

domain domain.net broadcast<br />

5 SSH SCP<br />

公 钥 认 证 (p21) | 指 纹 (p22) | SCP (p22) | 隧 道 (Tunneling) (p22)<br />

5.1 Public key authentication<br />

使 用 公 钥 认 证 而 不 是 密 码 连 接 主 机 。 方 法 是 附 加 你 的 公 钥 文 件 到 远 程 主 机 。 本 例 中 我 们 用 客 户 端 产 生 的 key 从<br />

host-client 连 接 到 host-server。<br />

• 使 用 ssh-keygen 生 成 密 钥 对 。 私 钥 放 在 ~/.ssh/id_dsa, 公 钥 在 ~/.ssh/id_dsa.pub。<br />

• 拷 贝 你 的 公 钥 到 服 务 器 的 ~/.ssh/authorized_keys2。<br />

# ssh-keygen -t dsa -N ''<br />

# cat ~/.ssh/id_dsa.pub | ssh you@host-server "cat - >> ~/.ssh/authorized_keys2"<br />

使 用 来 自 ssh.com 的 Windows 客 户 端<br />

ssh.com 的 非 商 业 性 版 本 的 客 户 端 可 下 载 自 它 主 FTP 站 点 :ftp.ssh.com/pub/ssh/。 用 ssh.com 客 户 端 产 生<br />

的 密 钥 需 要 在 OpenSSH 服 务 器 上 进 行 转 换 。 可 以 使 用 ssh-keygen 命 令 来 完 成 。<br />

• 使 用 ssh.com 客 户 端 创 建 一 对 密 钥 :Settings - User Authentication - Generate New....<br />

• 我 使 用 DSA 密 钥 类 型 ; 密 钥 长 度 为 2048。<br />

• 拷 贝 ssh.com 客 户 端 产 生 的 公 钥 到 服 务 器 的 ~/.ssh 目 录 。<br />

• 她 的 密 钥 对 在 C:\Documents and Settings\%USERNAME%\Application Data\SSH\UserKeys。<br />

• 在 服 务 器 上 使 用 ssh-keygen 转 换 公 钥 :<br />

# cd ~/.ssh<br />

# ssh-keygen -i -f keyfilename.pub >> authorized_keys2<br />

21


注 意 : 我 们 使 用 DSA 密 钥 , 使 用 RSA 密 钥 也 是 可 以 的 。 这 个 密 钥 不 受 密 码 保 护 。<br />

在 Windows 上 使 用 Putty<br />

Putty 24 是 一 个 简 单 并 且 自 由 的 (MIT 许 可 ) 25 ssh Windows 客 户 端 。<br />

• 使 用 puTTYgen 程 序 创 建 密 钥 对 。<br />

• 保 存 密 钥 对 ( 比 如 :C:\Documents and Settings\%USERNAME%\.ssh).<br />

• 拷 贝 公 钥 到 服 务 器 的 ~/.ssh 目 录 :<br />

# scp .ssh/puttykey.pub root@192.168.51.254:.ssh/<br />

• 使 用 ssh-keygen 在 OpenSSH 服 务 器 上 转 换 这 个 公 钥 :<br />

# cd ~/.ssh<br />

# ssh-keygen -i -f puttykey.pub >> authorized_keys2<br />

• 在 Putty 中 设 置 指 向 私 钥 的 位 置 :Connection - SSH - Auth<br />

5.2 检 查 指 纹<br />

在 首 次 连 接 时 ,SSH 会 请 求 保 存 不 知 道 的 主 机 指 纹 。 要 避 免 中 间 人 (man-in-the-middle) 攻 击 , 服 务 器 的 管 理 员<br />

可 以 发 送 密 钥 指 纹 给 客 户 端 , 来 让 其 在 首 次 登 陆 时 验 证 服 务 器 的 真 实 性 。 使 用 ssh-keygen -l 获 取 服 务 器 的 指<br />

纹 :<br />

# ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub # RSA 密 钥<br />

2048 61:33:be:9b:ae:6c:36:31:fd:83:98:b7:99:2d:9f:cd /etc/ssh/ssh_host_rsa_key.pub<br />

# ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub # DSA 密 钥 ( 默 认 )<br />

2048 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee /etc/ssh/ssh_host_dsa_key.pub<br />

现 在 客 户 端 在 连 接 到 服 务 器 时 可 验 证 其 服 务 器 的 真 实 性 :<br />

# ssh linda<br />

The authenticity of host 'linda (192.168.16.54)' can't be established.<br />

DSA key fingerprint is 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee.<br />

Are you sure you want to continue connecting (yes/no)? yes<br />

5.3 安 全 文 件 传 输<br />

一 些 简 单 的 命 令 :<br />

# scp file.txt host-two:/tmp<br />

# scp joe@host-two:/www/*.html /www/tmp<br />

# scp -r joe@host-two:/www /www/tmp<br />

在 Konqueror 或 Midnight 控 制 台 中 , 用 地 址 fish://user@gate 来 访 问 远 程 文 件 系 统 是 可 行 的 , 就 是 比 较 慢<br />

而 已 。<br />

此 外 , 也 可 以 用 基 于 SCP 文 件 系 统 客 户 端 的 sshfs 来 挂 载 一 个 远 程 目 录 。 看 fuse sshfs 26 .<br />

5.4 隧 道 (Tunneling)<br />

— SSH SCP —<br />

SSH 隧 道 可 以 让 你 通 过 SSH 连 接 进 行 端 口 转 发 ( 转 发 / 反 向 隧 道 ), 从 而 确 保 了 传 输 及 端 口 访 问 的 安 全 。 它 只 能 工<br />

作 在 TCP 协 议 上 。 通 常 端 口 转 发 命 令 如 下 ( 也 可 看 ssh 和 NAT 实 例 ):<br />

# ssh -L localport:desthost:destport user@gate # gate 为 目 标 主 机 网 关<br />

# ssh -R destport:desthost:localport user@gate # 转 发 你 的 localport 到 目 标 端 口<br />

# ssh -X user@gate # 转 发 X 程 序<br />

这 将 会 连 接 到 gate 并 转 发 端 口 到 目 标 主 机 desthost:destport。 注 意 desthost 为 gate 中 的 目 标 主 机 名 。 因<br />

此 , 如 果 连 接 到 了 gate, 那 么 desthost 就 是 localhost。 也 可 以 做 更 多 的 端 口 转 发 。<br />

24.http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html<br />

25. 译 注 :free 不 单 单 是 免 费<br />

26.http://fuse.sourceforge.net/sshfs.html<br />

22


— SSH SCP —<br />

在 gate 上 直 接 转 发<br />

假 设 我 们 想 访 问 在 gate 上 运 行 的 CVS(2401 端 口 ) 和 HTTP(80 端 口 )。 下 面 是 个 简 单 的 例 子 ,desthost 就 是<br />

localhost, 我 们 使 用 本 的 端 口 8080 代 替 80 端 口 , 所 以 我 们 不 需 要 root 权 限 。 一 旦 ssh session 打 开 , 二<br />

个 服 务 就 都 可 在 本 地 端 口 访 问 。<br />

# ssh -L 2401:localhost:2401 -L 8080:localhost:80 user@gate<br />

转 发 Netbios 和 远 程 桌 面 到 第 二 个 服 务 器<br />

假 设 有 一 台 在 gate 后 面 没 有 运 行 ssh 的 Winodws SMB 服 务 器 。 我 们 需 要 访 问 SMB 共 享 和 远 程 桌 面 。<br />

# ssh -L 139:smbserver:139 -L 3388:smbserver:3389 user@gate<br />

现 在 这 个 SMB 共 享 可 以 使 用 \\127.0.0.1\ 访 问 , 但 只 能 在 本 地 共 享 关 闭 的 情 况 下 , 因 为 本 的 共 享 也 是 在 139<br />

端 口 监 听 的 。<br />

保 持 本 的 共 享 也 是 可 行 的 , 因 此 我 们 需 要 为 这 个 通 道 使 用 新 IP 地 址 来 新 建 一 个 虚 拟 设 备 ,SMB 共 享 将 会 使 用 此<br />

地 址 连 接 。 此 外 , 本 地 RDP 已 经 在 3389 端 口 监 听 了 , 所 以 我 们 选 择 端 口 3388。 对 于 这 个 例 子 , 让 我 们 使 用 一<br />

个 虚 拟 IP 地 址 10.1.1.1。<br />

• 对 于 Putty 上 使 用 源 端 口 =10.1.1.1:139。 它 可 以 创 建 多 重 回 路 (multiple loop) 设 备 和 通 道 。 在<br />

Windows 2000 上 , 只 有 Putty 为 我 工 作 。<br />

• 对 于 ssh.com 的 客 户 端 , 要 禁 用 "Allow local connections only"。 因 为 ssh.com 客 户 端 绑 定 了 所 有<br />

地 址 , 所 以 只 能 连 接 单 个 共 享 。<br />

现 在 用 IP 地 址 10.1.1.1 创 建 回 路 (loopback) 接 口 :<br />

• # 系 统 -> 控 制 面 板 -> 添 加 硬 件 # 是 , 我 已 经 连 接 了 此 硬 件 (Y) # 添 加 新 的 硬 件 设 备 ( 在 列 表 最 下 面 )。<br />

• # 安 装 我 手 动 选 择 的 硬 件 # 网 络 适 配 器 # Microsoft , Microsoft Loopback Adapter。<br />

• 配 置 这 个 假 设 备 的 IP 地 址 为 10.1.1.1, 掩 码 255.255.255.0, 没 有 网 关 。<br />

• 高 级 ->WINS, 开 启 LMHOSTS 查 询 ; 禁 用 TCP/IP 上 的 NetBIOS。<br />

• # 启 用 Microsoft 网 络 客 户 端 。# 禁 用 Microsoft 网 络 文 件 和 打 印 机 共 享<br />

做 完 这 些 之 后 我 有 重 启 。 现 在 用 \\10.1.1.1 连 接 SMB 共 享 和 用 10.1.1.1:3388 连 接 远 程 桌 面 。<br />

调 试<br />

如 果 不 能 工 作 :<br />

• 端 口 有 没 有 转 发 : 运 行 控 制 台 运 行 netstat -an 命 令 并 查 看 有 没 有 0.0.0.0:139 或 者 10.1.1.1:139<br />

• 有 没 有 telnet 到 10.1.1.1 139?<br />

• 你 需 要 打 开 " 本 地 端 口 接 受 其 他 主 机 连 接 "。<br />

• "Microsoft 网 络 文 件 和 打 印 机 共 享 " 有 没 有 被 禁 用 ?<br />

在 NAT 后 面 连 接 两 个 客 户 端<br />

假 设 两 个 客 户 端 在 一 个 NAT 网 关 后 面 ,cliadmin 客 户 端 要 连 接 到 cliuser 客 户 端 ( 目 的 地 ), 两 者 都 可 用 ssh<br />

登 录 到 正 在 运 行 sshd 的 gate 上 。 你 不 需 要 root 权 限 , 只 要 端 口 大 于 1024 即 可 。 我 们 在 gate 上 使 用<br />

2022 端 口 。 而 且 , 由 于 gate 使 用 与 本 地 , 所 以 网 关 端 口 不 是 必 须 的 。<br />

开 启 cliuser 客 户 端 ( 从 目 标 到 gate):<br />

# ssh -R 2022:localhost:22 user@gate # 转 发 客 户 端 22 端 口 到 gate:2022 端 口<br />

开 启 cliadmin 客 户 端 ( 从 主 机 到 gate):<br />

# ssh -L 3022:localhost:2022 admin@gate # 转 发 客 户 端 3022 端 口 到 gate:2022 端 口<br />

现 在 admin 可 以 直 接 连 接 cliuser 客 户 端 :<br />

# ssh -p 3022 admin@localhost # local:3022 -> gate:2022 -> client:22<br />

在 NAT 后 面 的 VNC 连 接<br />

假 设 一 个 在 NAT 后 面 , 监 听 在 端 口 5900 上 可 被 访 问 的 Windows VNC 客 户 端 。<br />

开 启 cliwin 客 户 端 到 gate:<br />

# ssh -R 15900:localhost:5900 user@gate<br />

开 启 cliadmin 客 户 端 ( 从 主 机 到 gate):<br />

# ssh -L 5900:localhost:15900 admin@gate<br />

23


— 使 用 SSH 建 立 VPN —<br />

现 在 admin 直 接 连 接 到 VNC 客 户 端 :<br />

# vncconnect -display :0 localhost<br />

6 使 用 SSH 建 立 VPN<br />

自 4.3 版 开 始 ,OpenSSH 可 以 使 用 tun/tap 27 设 备 来 加 密 一 个 隧 道 。 其 非 常 类 似 于 基 于 TLS 的 VPN 解 决 方 案<br />

( 像 OpenVPN)。 对 于 SSH 的 一 个 优 势 是 , 她 不 需 要 安 装 和 配 置 额 外 的 软 件 。 另 外 隧 道 使 用 SSH 认 证 ( 像 共 享 密<br />

钥 )。 其 缺 点 是 , 对 于 一 个 缓 慢 的 连 接 , 其 传 输 效 率 较 低 。 并 且 这 个 隧 道 依 赖 于 单 个 ( 易 断 的 ) TCP 链 接 。 这 个<br />

技 术 对 于 快 速 设 置 一 个 基 于 IP 的 VPN 来 说 非 常 有 用 。 她 对 于 用 单 个 TCP 端 口 转 发 没 有 限 制 , 并 且 在 所 有 3/4<br />

层 协 议 像 ICMP、TCP/UDP 等 上 都 可 用 。 不 管 怎 么 样 , 下 面 这 些 选 择 在 sshd_conf 文 件 中 是 必 须 的 :<br />

PermitRootLogin yes<br />

PermitTunnel yes<br />

6.1 单 个 P2P 连 接<br />

这 里 , 我 们 用 点 对 点 隧 道 连 接 hclient 和 hserver 两 个 主 机 。 这 个 连 接 是 从 hclient 开 始 到 hserver 的 , 并<br />

且 是 用 root 来 做 。 这 个 通 道 的 连 接 点 是 10.0.1.1( 服 务 端 ) 和 10.0.1.2( 客 户 端 ), 然 后 我 们 创 建 设 备 tun5( 当<br />

然 也 可 以 是 其 它 数 字 )。 这 个 过 程 非 常 简 单 :<br />

• 使 用 SSH 的 通 道 选 项 -w 来 连 接<br />

• 设 置 隧 道 的 IP 地 址 。 服 务 端 和 客 户 端 各 一 次 。<br />

连 接 到 服 务 端<br />

连 接 始 于 客 户 端 , 然 后 再 服 务 端 执 行 命 令 。<br />

Linux 上 的 服 务 端<br />

cli># ssh -w5:5 root@hserver<br />

srv># ifconfig tun5 10.0.1.1 netmask 255.255.255.252<br />

FreeBSD 上 的 服 务 端<br />

cli># ssh -w5:5 root@hserver<br />

srv># ifconfig tun5 10.0.1.1 10.0.1.2<br />

# 在 服 务 端 shell 上 执 行<br />

# 在 服 务 端 shell 上 执 行<br />

连 接 到 客 户 端<br />

在 客 户 端 上 执 行 命 令 :<br />

cli># ifconfig tun5 10.0.1.2 netmask 255.255.255.252<br />

cli># ifconfig tun5 10.0.1.2 10.0.1.1<br />

# Linux 上 的 客 户 端<br />

# FreeBSD 上 的 客 户 端<br />

现 在 两 个 主 机 都 连 上 了 , 并 且 可 以 在 任 何 3/4 层 协 议 上 使 用 此 通 道 IP 地 址 透 明 的 通 讯 。<br />

6.2 连 接 两 个 网 络<br />

除 上 面 的 p2p 设 置 外 , 一 个 更 有 用 的 是 SSH VPN 用 两 个 gate 连 接 两 个 私 有 网 络 。 假 设 有 这 样 一 个 例 子 ,netA<br />

为 192.168.51.0/24 还 有 netB 为 192.168.16.0/24。 设 置 过 程 同 上 面 相 似 , 我 们 只 需 要 添 加 routing。 如 果<br />

gate 不 同 于 默 认 网 关 , 那 在 私 有 网 络 接 口 上 必 须 开 启 NAT。<br />

192.168.51.0/24 (netA)|gateA gateB|192.168.16.0/24 (netB)<br />

• 使 用 隧 道 选 项 -w 连 接 SSH。<br />

• 配 置 隧 道 的 IP 地 址 。 服 务 端 和 客 户 端 各 一 次 。<br />

• 为 两 个 网 络 添 加 routing。<br />

• 如 果 需 要 , 在 gate 的 私 有 网 络 接 口 上 开 启 NAT。<br />

设 置 是 从 netA 中 的 gasteA 开 始 的 .<br />

27. 译 注 :tun 为 虚 拟 点 对 点 设 备 ,tap 为 虚 拟 以 太 网 设 备 。<br />

24


— RSYNC —<br />

连 接 gateA 到 gateB<br />

连 接 从 gateA 开 始 , 命 令 执 行 于 gateB。<br />

Linux 上 的 gateB<br />

gateA># ssh -w5:5 root@gateB<br />

gateB># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # 在 gateB 的 shell 中 执 行<br />

gateB># route add -net 192.168.51.0 netmask 255.255.255.0 dev tun5<br />

gateB># echo 1 > /proc/sys/net/ipv4/ip_forward # 如 果 不 是 默 认 网 关<br />

gateB># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE<br />

FreeBSD 上 的 gateB<br />

gateA># ssh -w5:5 root@gateB<br />

# 创 建 tun5 设 备<br />

gateB># ifconfig tun5 10.0.1.1 10.0.1.2<br />

# 在 gateB 的 shell 中 执 行<br />

gateB># route add 192.168.51.0/24 10.0.1.2<br />

gateB># sysctl net.inet.ip.forwarding=1<br />

# 如 果 不 是 默 认 网 关<br />

gateB># natd -s -m -u -dynamic -n fxp0 # 看 NAT (page 17)<br />

gateA># sysctl net.inet.ip.fw.enable=1<br />

配 置 gateA<br />

在 gateA 上 执 行 命 令 :<br />

Linux 上 的 gateA<br />

gateA># ifconfig tun5 10.0.1.2 netmask 255.255.255.252<br />

gateA># route add -net 192.168.16.0 netmask 255.255.255.0 dev tun5<br />

gateA># echo 1 > /proc/sys/net/ipv4/ip_forward<br />

gateA># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE<br />

FreeBSD 上 的 gateA<br />

gateA># ifconfig tun5 10.0.1.2 10.0.1.1<br />

gateA># route add 192.168.16.0/24 10.0.1.2<br />

gateA># sysctl net.inet.ip.forwarding=1<br />

gateA># natd -s -m -u -dynamic -n fxp0 # 看 NAT (page 17)<br />

gateA># sysctl net.inet.ip.fw.enable=1<br />

现 在 两 个 私 有 网 络 都 可 以 通 过 SSH VPN 来 透 明 的 连 接 。 如 果 gate 不 是 默 认 网 关 , 那 么 IP 转 发 和 NAT 设 置 都<br />

是 必 须 的 。 在 这 种 情 况 下 , 客 户 端 将 不 知 道 在 哪 里 转 发 响 应 (response), 并 且 NAT 必 须 是 开 启 的 。<br />

7 RSYNC<br />

Rsync 差 不 多 可 以 代 替 cp 和 scp, 此 外 , 断 点 续 传 是 重 启 有 效 的 。 尾 部 的 斜 杠 也 有 着 不 同 的 意 思 , 请 阅 读 man<br />

页 面 ...... 这 里 有 一 些 例 子 :<br />

拷 贝 目 录 中 所 有 内 容 :<br />

# rsync -a /home/colin/ /backup/colin/<br />

# rsync -a /var/ /var_bak/<br />

# rsync -aR --delete-during /home/user/ /backup/ # 使 用 相 对 路 径 ( 看 下 面 )<br />

同 之 前 一 样 , 但 使 用 了 压 缩 和 网 络 。Rsync 使 用 SSH 进 行 传 输 , 并 且 使 用 SSH 密 钥 , 如 果 设 置 的 话 。 和 SCP<br />

一 样 使 用 ":"。 一 个 典 型 的 拷 贝 :<br />

# rsync -axSRzv /home/user/ user@server:/backup/user/<br />

排 除 在 /home/user/ 中 任 何 tmp 目 录 , 并 且 保 持 相 对 目 录 层 次 结 构 , 远 程 目 录 的 结 构 就 是 /backup/home/<br />

user/。 典 型 的 用 于 备 份 的 命 令 。<br />

# rsync -azR --exclude /tmp/ /home/user/ user@server:/backup/<br />

SSH 连 接 使 用 端 口 20022:<br />

# rsync -az -e 'ssh -p 20022' /home/colin/ user@server:/backup/colin/<br />

25


使 用 rsync 守 护 进 程 ( 使 用 "::") 是 很 快 的 , 但 没 有 透 过 SSH 加 密 。 位 置 /backup 定 义 在 了 配 置 文 件 /etc/<br />

rsyncd.conf 中 。 变 量 RSYNC_PASSWORD 可 以 设 置 用 来 免 除 手 动 输 入 密 码 。<br />

# rsync -axSRz /home/ ruser@hostname::rmodule/backup/<br />

# rsync -axSRz ruser@hostname::rmodule/backup/ /home/ # 回 拷 贝<br />

一 些 重 要 选 项 :<br />

-a, --archive<br />

-r, --recursive<br />

-R, --relative<br />

-H, --hard-links<br />

-S, --sparse<br />

-x, --one-file-system<br />

--exclude=PATTERN<br />

--delete-during<br />

--delete-after<br />

7.1 在 Windows 上 使 用 Rsync<br />

归 档 模 式 , 等 于 -rlptgoD ( 非 -H)<br />

对 子 目 录 以 递 归 模 式 处 理<br />

使 用 相 对 路 径 名<br />

保 留 硬 链 结<br />

对 稀 疏 文 件 进 行 特 殊 处 理 以 节 省 DST 的 空 间<br />

不 跨 越 文 件 系 统 边 界<br />

指 定 排 除 不 需 要 传 输 的 文 件 模 式<br />

传 输 期 间 删 除<br />

传 输 结 束 以 后 再 删 除<br />

可 以 通 过 cygwin 或 独 立 打 包 的 cwrsync 28 来 在 Windows 上 运 行 rsync。 这 对 于 自 动 备 份 来 说 非 常 方 便 。 只 装<br />

其 中 一 个 ( 不 是 两 个 ), 然 后 添 加 路 径 到 Windows 系 统 变 量 中 :# 控 制 面 板 -> 系 统 -> 高 级 标 签 , 环 境 变 量 按<br />

钮 。 编 辑 "Path" 添 加 rsync 的 安 装 路 径 , 比 如 :C:\Program Files\cwRsync\bin 或 者 C:\cygwin\bin。 这 可<br />

以 让 rsync 和 ssh 可 用 于 Windows 命 令 窗 口 中 。<br />

公 钥 认 证<br />

Rsync 是 自 动 使 用 SSH 隧 道 的 , 因 此 在 服 务 端 使 用 SSH 认 证 。 自 动 备 份 可 免 受 用 户 的 影 响 ,rsync 命 令 对 于 使<br />

用 SSH 公 钥 认 证 可 以 不 需 要 密 码 。<br />

下 面 所 有 的 命 令 都 可 在 windows 控 制 台 中 执 行 。 在 控 制 台 ( 开 始 -> 运 行 -> cmd) 中 像 在 SSH 中 描 述 的 那 样 创<br />

建 和 上 传 密 钥 , 根 据 你 的 情 况 改 变 "user" 和 "server"。 如 果 文 件 authorized_keys2 不 存 在 , 拷 贝<br />

id_dsa.pub 成 authorized_keys2 并 上 传 它 。<br />

# ssh-keygen -t dsa -N '' # 创 建 密 钥 对<br />

# rsync user@server:.ssh/authorized_keys2 . # 从 服 务 器 拷 贝 本 地 文 件<br />

# cat id_dsa.pub >> authorized_keys2 # 或 者 使 用 编 辑 器 添 加 这 个 公 钥<br />

# rsync authorized_keys2 user@server:.ssh/ # 拷 贝 文 件 回 服 务 器<br />

# del authorized_keys2 # 删 除 本 地 拷 贝<br />

现 在 测 试 一 下 ( 在 同 一 行 里 面 ):<br />

rsync -rv "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \<br />

'user@server:My\ Documents/'<br />

自 动 备 份<br />

— RSYNC —<br />

使 用 批 处 理 文 件 自 动 备 份 并 添 加 到 任 务 计 划 ( 程 序 -> 附 件 -> 系 统 工 具 -> 任 务 计 划 )。 举 个 例 子 , 创 建 批 处 理<br />

文 件 backup.bat 取 代 user@server。<br />

@ECHO OFF<br />

REM rsync the directory My Documents<br />

SETLOCAL<br />

SET CWRSYNCHOME=C:\PROGRAM FILES\CWRSYNC<br />

SET CYGWIN=nontsec<br />

SET CWOLDPATH=%PATH%<br />

REM uncomment the next line when using cygwin<br />

SET PATH=%CWRSYNCHOME%\BIN;%PATH%<br />

echo Press Control-C to abort<br />

rsync -av "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \<br />

'user@server:My\ Documents/'<br />

pause<br />

28.http://sourceforge.net/projects/sereds<br />

26


8 SUDO<br />

— SUDO —<br />

Sudo 可 以 给 用 户 一 些 超 级 用 户 的 权 限 而 不 需 要 root 密 码 。Sudo 对 于 一 个 服 务 器 和 工 作 站 混 合 的 多 用 户 环 境 来<br />

说 非 常 有 用 。 使 用 sudo 运 行 命 令 :<br />

# sudo /etc/init.d/dhcpd restart # 用 root 权 限 运 行 rc 脚 本<br />

# sudo -u sysadmin whoami # 使 用 其 他 用 户 运 行 命 令<br />

8.1 配 置<br />

Sudo 的 配 置 在 /etc/sudoers 中 , 并 且 只 能 用 visudo 编 辑<br />

29<br />

。 其 基 本 语 法 是 ( 列 表 是 以 逗 号 分 隔 的 ):<br />

user hosts = (runas) commands<br />

# 在 /etc/sudoers 中<br />

users 一 个 或 多 个 用 户 或 是 % 用 户 组 ( 像 %wheel) 来 获 得 权 限<br />

hosts 主 机 列 表 ( 或 ALL)<br />

runas 列 出 用 户 以 何 种 身 份 ( 或 ALL) 来 执 行 命 令 , 放 在 ( ) 内 !<br />

commands 列 出 可 被 users 以 runas 或 root 权 限 运 行 的 命 令 ( 或 ALL)<br />

另 外 一 些 关 键 字 可 以 定 义 别 名 , 他 们 是 User_Alias, Host_Alias, Runas_Alias 和 Cmnd_Alias。 这 对 于 一 些 较<br />

大 的 设 置 比 较 有 用 。 下 面 是 sudoers 例 子 :<br />

# cat /etc/sudoers<br />

# 主 机 别 名<br />

Host_Alias DMZ = 212.118.81.40/28<br />

Host_Alias DESKTOP = work1, work2<br />

# 用 户 别 名 和 runas 别 名<br />

User_Alias ADMINS = colin, luca, admin<br />

User_Alias DEVEL = joe, jack, julia<br />

Runas_Alias DBA = oracle,pgsql<br />

# 命 令 别 名 , 其 值 为 全 路 径 命 令<br />

Cmnd_Alias SYSTEM = /sbin/reboot,/usr/bin/kill,/sbin/halt,/sbin/shutdown,/etc/init.d/<br />

Cmnd_Alias PW = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root # Not root pwd!<br />

Cmnd_Alias DEBUG = /usr/sbin/tcpdump,/usr/bin/wireshark,/usr/bin/nmap<br />

# 一 个 真 实 的 规 则<br />

root,ADMINS ALL = (ALL) NOPASSWD: ALL # ADMINS 别 名 中 的 用 户 可 做 任 何 事 情 不 需 要 密 码<br />

DEVEL DESKTOP = (ALL) NOPASSWD: ALL # 开 发 人 员 可 在 DESKTOP 别 名 的 主 机 上 做 任 何 事 情<br />

DEVEL DMZ = (ALL) NOPASSWD: DEBUG # 开 发 人 员 可 以 在 DMZ 别 名 的 主 机 上 使 用 DEBUG 别 名 中 的 命 令<br />

# 用 户 sysadmin 可 以 在 DMZ 服 务 器 上 执 行 一 些 命 令<br />

sysadmin DMZ = (ALL) NOPASSWD: SYSTEM,PW,DEBUG<br />

sysadmin ALL,!DMZ = (ALL) NOPASSWD: ALL # 可 以 在 非 DMZ 主 机 上 做 任 何 事 情<br />

%dba ALL = (DBA) ALL # 用 户 组 dba 可 以 运 行 DBA 别 名 中 用 户 权 限 的 所 有 命 令<br />

# 所 有 用 户 可 以 在 DESKTOP 别 名 的 主 机 上 挂 载 / 卸 载 CD-ROM<br />

ALL DESKTOP = NOPASSWD: /sbin/mount /cdrom,/sbin/umount /cdrom<br />

9 文 件 加 密<br />

9.1 单 个 文 件<br />

加 密 和 解 密 :<br />

# openssl des -salt -in file -out file.des<br />

# openssl des -d -salt -in file.des -out file<br />

那 个 file 可 以 是 归 档 文 件 (tar archive)。<br />

29. 译 注 : 并 不 是 说 不 能 用 其 他 编 辑 器 编 辑 , 而 是 因 为 visudo 会 对 其 语 法 进 行 严 格 检 查 , 避 免 给 系 统 带 来 严 重 后 果 。<br />

27


— 文 件 加 密 —<br />

9.2 归 档 并 加 密 整 个 目 录<br />

# tar -cf - directory | openssl des -salt -out directory.tar.des # 加 密<br />

# openssl des -d -salt -in directory.tar.des | tar -x # 解 密<br />

9.3 压 缩 归 档 并 加 密 整 个 目 录<br />

# tar -zcf - directory | openssl des -salt -out directory.tar.gz.des # 加 密<br />

# openssl des -d -salt -in directory.tar.gz.des | tar -xz # 解 密<br />

• 在 使 用 -k mysecretpassword 后 ,des 会 取 消 交 互 式 的 密 码 请 求 。 不 过 , 这 非 常 不 安 全 。<br />

• 使 用 des3 代 替 des 来 获 得 更 强 的 加 密 (Triple-DES Cipher)。 这 同 样 会 消 耗 更 多 的 CPU。<br />

9.4 GPG<br />

GnuPG 是 众 所 周 知 的 对 邮 件 或 任 何 数 据 进 行 加 密 和 签 名 的 软 件 。 此 外 ,gpg 还 提 供 高 级 密 钥 管 理 系 统 。 此 章 节 只<br />

涵 盖 了 文 件 加 密 , 没 有 邮 件 加 密 、 签 名 或 者 信 任 网 络 (Web-Of-Trust)。<br />

单 纯 的 加 密 是 一 个 对 称 式 的 加 密 算 法 (symmetric cipher)。 在 本 例 中 , 文 件 是 用 一 个 秘 密 来 加 密 的 , 任 何 人 知 道<br />

了 这 个 密 码 都 可 以 对 其 进 行 解 密 , 因 此 就 不 需 要 密 钥 。Gpg 添 加 后 缀 ".gpg" 到 已 加 密 的 文 件 名 。<br />

# gpg -c file # 使 用 密 码 加 密 文 件<br />

# gpg file.gpg # 文 件 解 密 ( 选 项 -o 其 他 文 件 )<br />

使 用 密 钥<br />

对 于 更 详 细 的 请 看 GPG 快 速 上 手<br />

30<br />

和 GPG/PGP 基 础<br />

31<br />

, 特 别 是 gnupg 文 档<br />

32<br />

。<br />

密 钥 对 ( 私 钥 , 公 钥 ) 为 非 对 称 加 密 技 术 。 要 点 如 下 :<br />

• 你 的 公 钥 是 用 来 给 别 人 加 密 文 件 的 并 且 只 有 你 作 为 接 收 者 才 可 以 解 密 ( 甚 至 不 是 一 个 人 加 密 的 文 件 也 可 以<br />

解 密 )。 公 钥 是 公 开 的 也 就 意 味 着 可 以 分 发 。<br />

• 用 你 的 密 码 加 密 的 私 钥 用 来 解 密 用 你 的 公 钥 加 密 的 文 件 。 这 个 密 钥 必 须 保 持 安 全 。 因 为 如 果 遗 失 了 私 钥<br />

或 者 密 码 , 那 么 所 有 的 文 件 都 是 使 用 你 的 公 钥 加 密 的 。<br />

• 多 个 密 钥 文 件 被 称 为 密 钥 环 (keyrings), 她 可 以 包 含 一 个 以 上 的 密 钥 。<br />

首 先 生 成 密 钥 对 。 使 用 默 认 就 行 , 但 你 至 少 要 输 入 你 的 全 名 、 邮 件 地 址 和 可 选 注 释 。 该 注 释 对 于 创 建 相 同 的 名 字<br />

和 邮 件 地 址 的 多 个 密 钥 来 说 非 常 有 用 。 此 外 , 你 应 该 使 用 " 口 令 (passphrase)", 而 不 是 简 单 的 密 码 。<br />

# gpg --gen-key # 这 需 要 一 些 时 间<br />

在 <strong>Unix</strong> 上 密 钥 存 储 在 ~/.gnupg/ 中 , 在 Windows 上 通 常 存 储 在<br />

C:/Documents and Settings/%USERNAME%/Application Data/gnupg/ 中 。<br />

~/.gnupg/pubring.gpg<br />

~/.gnupg/secring.gpg<br />

# 包 含 你 的 公 钥 和 所 有 其 他 导 入 的 信 息<br />

# 可 包 含 多 个 私 钥<br />

常 用 选 项 的 简 短 描 述 :<br />

-e 加 密 数 据<br />

-d 解 密 数 据<br />

-r 为 某 个 收 件 者 加 密 (' 全 名 ' 或 者 'email@domain')<br />

-a 输 出 经 过 ascii 封 装 的 密 钥<br />

-o 指 定 输 出 文 件<br />

本 实 例 使 用 'Your Name' 和 'Alice' 作 为 密 钥 的 email 或 全 名 或 部 分 名 字 的 参 考 。 举 个 例 子 , 我 可 以 使 用<br />

'Colin' or 'c@cb.vu' 给 我 的 密 钥 [Colin Barschel (cb.vu) ]。<br />

只 用 于 个 人 的 加 密<br />

不 需 要 导 出 / 导 入 任 何 密 钥 , 因 为 你 都 已 经 有 了 。<br />

# gpg -e -r 'Your Name' file # 使 用 你 的 公 钥 加 密<br />

# gpg -o file -d file.gpg # 解 密 。 使 用 -o 指 定 输 出 文 件<br />

30.http://www.madboa.com/geek/gpg-quickstart<br />

31.http://aplawrence.com/Basics/gpg.html<br />

32.http://gnupg.org/documentation<br />

28


— 分 区 加 密 —<br />

用 密 钥 加 密 - 解 密<br />

首 先 你 需 要 导 出 给 别 人 使 用 的 公 钥 。 并 且 你 需 要 导 入 来 自 Alice 她 所 加 密 文 件 的 公 钥 。 你 可 以 用 简 单 的 ascii<br />

文 档 或 者 使 用 公 钥 服 务 器 来 保 存 这 些 密 钥 。<br />

举 个 例 子 ,Alice 导 出 她 的 公 钥 , 然 后 你 导 入 它 , 之 后 你 就 可 以 加 密 一 个 文 件 给 她 。 这 个 加 密 文 件 只 有 Alice<br />

可 以 解 密 。<br />

# gpg -a -o alicekey.asc --export 'Alice' # Alice 导 出 她 的 公 钥 到 ascii 文 件 中<br />

# gpg --send-keys --keyserver subkeys.pgp.net KEYID # Alice 把 她 的 公 钥 放 入 一 个 服 务 器<br />

# gpg --import alicekey.asc # 你 导 入 她 的 密 钥 到 你 的 公 钥 环 (pubring) 中<br />

# gpg --search-keys --keyserver subkeys.pgp.net 'Alice' # 或 者 从 一 个 服 务 器 中 获 取 他 的 公 钥<br />

一 旦 这 些 公 钥 导 入 后 , 加 密 或 解 密 一 个 文 件 会 非 常 简 单 :<br />

# gpg -e -r 'Alice' file # 给 Alice 加 密 文 件<br />

# gpg -d file.gpg -o file # 解 密 Alice 给 你 的 加 密 文 件<br />

密 钥 管 理<br />

# gpg --list-keys # 列 出 所 有 公 钥 并 查 看 其 KEYID<br />

KEYID 跟 在 '/' 后 面 比 如 :pub 1024D/D12B77CE 它 的 KEYID 是 D12B77CE<br />

# gpg --gen-revoke 'Your Name' # 产 生 一 份 撤 销 密 钥 证 书<br />

# gpg --list-secret-keys # 列 出 所 有 私 钥<br />

# gpg --delete-keys NAME # 从 本 的 密 钥 环 中 删 除 一 个 公 钥<br />

# gpg --delete-secret-key NAME # 从 本 的 密 钥 环 中 删 除 一 个 私 钥<br />

# gpg --fingerprint KEYID # 显 示 KIYID 这 个 密 钥 的 指 纹<br />

# gpg --edit-key KEYID # 编 辑 密 钥 ( 比 如 签 名 或 者 添 加 / 删 除 email)<br />

10 分 区 加 密<br />

Linux with LUKS (p29) | Linux dm-crypt only (p30) | FreeBSD GELI (p30) | FreeBSD 只 使 用 密 码 (p31)<br />

有 ( 许 多 ) 其 他 替 代 方 法 来 加 密 磁 盘 , 我 只 呈 现 我 所 知 道 和 使 用 的 方 法 。 请 记 住 , 安 全 只 是 系 统 还 未 经 过 实 际 考 验<br />

而 已 。 入 侵 者 可 以 轻 易 通 过 键 盘 事 件 记 录 密 码 。 此 外 , 当 已 经 加 载 了 分 区 , 其 数 据 是 可 以 自 由 访 问 的 , 并 不 会 阻<br />

止 入 侵 者 去 访 问 它 。<br />

10.1 Linux<br />

这 部 分 我 们 使 用 可 用 于 2.6 内 核 的 Linux dm-crypt (device-mapper)。 在 这 个 实 例 中 , 让 我 们 加 密 /dev/sdc1<br />

分 区 , 它 可 为 任 何 其 他 分 区 、 磁 盘 、USB 或 者 用 losetup 创 建 的 基 于 文 件 的 分 区 。 对 于 基 于 文 件 的 分 区 , 我 们 使<br />

用 /dev/loop0。 看 镜 像 文 件 分 区 。Device mapper 利 用 标 签 来 标 识 一 个 分 区 。 我 们 使 用 sdc1 作 为 此 标 签 , 但<br />

可 以 为 任 何 字 符 串 。<br />

dm-crypt with LUKS<br />

LUKS 和 dm-crypt 是 较 好 的 加 密 技 术 , 并 且 可 为 同 一 个 分 区 设 置 多 个 口 令 , 更 改 密 码 也 很 方 便 。 可 简 单 输 入 #<br />

cryptsetup --help 来 测 试 LUKS 是 否 可 用 。 如 果 没 有 显 示 任 何 关 于 LUKS 的 信 息 , 可 看 下 面 Without LUKS 的<br />

介 绍 。 第 一 步 如 果 需 要 的 话 创 建 一 个 分 区 :fdisk /dev/sdc。<br />

创 建 加 密 分 区<br />

# dd if=/dev/urandom of=/dev/sdc1 # 可 选<br />

# cryptsetup -y luksFormat /dev/sdc1 # 这 破 坏 了 在 sdc1 上 的 数 据<br />

# cryptsetup luksOpen /dev/sdc1 sdc1<br />

# mkfs.ext3 /dev/mapper/sdc1 # 创 建 ext3 文 件 系 统<br />

# mount -t ext3 /dev/mapper/sdc1 /mnt<br />

# umount /mnt<br />

# cryptsetup luksClose sdc1 # Detach 已 加 密 的 分 区<br />

Attach<br />

# cryptsetup luksOpen /dev/sdc1 sdc1<br />

# mount -t ext3 /dev/mapper/sdc1 /mnt<br />

29


— 分 区 加 密 —<br />

Detach<br />

# umount /mnt<br />

# cryptsetup luksClose sdc1<br />

dm-crypt without LUKS<br />

# cryptsetup -y create sdc1 /dev/sdc1 # 或 任 何 其 他 分 区 像 /dev/loop0<br />

# dmsetup ls # 检 查 一 下 , 将 显 示 :sdc1 (254, 0)<br />

# mkfs.ext3 /dev/mapper/sdc1 # 只 有 第 一 次 要 这 么 做 !<br />

# mount -t ext3 /dev/mapper/sdc1 /mnt<br />

# umount /mnt/<br />

# cryptsetup remove sdc1 # Detach 已 加 密 的 分 区<br />

这 样 做 等 同 于 ( 非 mkfs 部 分 ) re-attach 分 区 。 如 果 密 码 不 正 确 ,mount 命 令 将 会 失 败 。 对 于 这 个 例 子 , 只 要<br />

简 单 的 移 除 sdc1 (cryptsetup remove sdc1) 并 重 建 即 可 。<br />

10.2 FreeBSD<br />

两 个 流 行 的 FreeBSD 磁 盘 加 密 模 块 为 gbde 和 geli。 我 现 在 使 用 geli 原 因 是 它 够 快 并 且 它 使 用 加 解 密 硬 件 加<br />

速 设 备 。 详 情 可 看 FreeBSD 使 用 手 册 18.6 33 。geli 模 块 必 须 已 编 译 或 加 载 进 内 核 :<br />

options GEOM_ELI<br />

device crypto<br />

# 内 核 配 置 文 件 中 加 入 这 两 行<br />

# echo 'geom_eli_load="YES"' >> /boot/loader.conf # 也 可 以 在 系 统 引 导 时 加 载 或 者 做 :kldload geom_eli<br />

使 用 密 码 和 密 钥<br />

我 为 一 个 典 型 的 磁 盘 加 密 使 用 这 些 设 置 , 其 使 用 了 一 个 口 令 和 一 个 加 密 主 密 钥 (master key) 的 密 钥 。 这 意 味 着 你<br />

需 要 密 码 和 生 产 的 密 钥 /root/ad1.key 来 attach 分 区 。 主 密 钥 存 储 在 这 个 加 密 分 区 中 并 且 不 可 见 。 看 下 面 为<br />

USB 或 映 像 文 件 的 加 密 设 置 。<br />

创 建 加 密 分 区<br />

# dd if=/dev/random of=/root/ad1.key bs=64 count=1 # 加 密 主 密 钥 的 密 钥<br />

# geli init -s 4096 -K /root/ad1.key /dev/ad1 # 对 于 磁 盘 也 可 用 -s 8192<br />

# geli attach -k /root/ad1.key /dev/ad1 # 将 /dev/ad1 与 所 生 成 的 密 钥 /root/ad1.key 关 联<br />

# dd if=/dev/random of=/dev/ad1.eli bs=1m # 可 选 , 需 要 很 长 时 间<br />

# newfs /dev/ad1.eli # 创 建 文 件 系 统<br />

# mount /dev/ad1.eli /mnt<br />

Attach<br />

# geli attach -k /root/ad1.key /dev/ad1<br />

# fsck -ny -t ffs /dev/ad1.eli # 检 查 文 件 系 统<br />

# mount /dev/ad1.eli /mnt<br />

Detach<br />

Detach 步 骤 会 在 关 机 时 自 动 完 成 。<br />

# umount /mnt<br />

# geli detach /dev/ad1.eli<br />

/etc/fstab<br />

加 密 分 区 在 /etc/fstab 中 配 置 成 自 动 加 载 。 系 统 启 动 时 会 询 问 加 密 分 区 的 密 码 。 对 于 本 例 下 列 设 置 是 必 须 的 :<br />

# grep geli /etc/rc.conf<br />

geli_devices="ad1"<br />

geli_ad1_flags="-k /root/ad1.key"<br />

# grep geli /etc/fstab<br />

/dev/ad1.eli /home/private ufs rw 0 0<br />

33.http://www.freebsd.org/handbook/disks-encrypting.html<br />

30


— SSL 认 证 —<br />

仅 用 密 码<br />

加 密 一 个 USB stick 或 者 映 像 文 件 使 用 密 码 而 不 是 密 钥 来 得 更 方 便 。 这 种 情 况 下 , 没 有 必 要 随 身 携 带 额 外 的 密<br />

钥 文 件 。 所 做 步 骤 同 上 面 非 常 相 似 , 只 是 不 需 要 密 钥 文 件 。 让 我 们 来 加 密 一 个 1 GB 的 映 像 文 件 /cryptedfile。<br />

# dd if=/dev/zero of=/cryptedfile bs=1M count=1000 # 1 GB 文 件<br />

# mdconfig -at vnode -f /cryptedfile<br />

# geli init /dev/md0 # 仅 用 密 码 加 密<br />

# geli attach /dev/md0<br />

# newfs -U -m 0 /dev/md0.eli<br />

# mount /dev/md0.eli /mnt<br />

# umount /dev/md0.eli<br />

# geli detach md0.eli<br />

现 在 可 以 把 这 个 映 像 文 件 加 载 成 仅 需 密 码 的 文 件 系 统 。<br />

# mdconfig -at vnode -f /cryptedfile<br />

# geli attach /dev/md0<br />

# mount /dev/md0.eli /mnt<br />

11 SSL 认 证<br />

所 谓 的 SSL/TLS 认 证 是 加 密 的 公 钥 认 证 , 它 由 一 个 公 用 密 钥 和 私 用 密 钥 组 成 。 证 书 用 来 认 证 终 端 和 加 密 数 据<br />

的 。 例 如 , 用 在 web 服 务 器 (https) 或 者 邮 件 服 务 器 (imaps)。<br />

11.1 步 骤<br />

• 我 们 需 要 一 个 证 书 颁 发 机 构 来 签 署 我 们 的 证 书 。 这 一 步 通 常 由 供 应 商 提 供 , 如 Thawte、Verisign 等 。 不<br />

过 , 我 们 也 可 以 创 建 我 们 自 己 的 。<br />

• 创 建 一 个 证 书 签 发 申 请 (signing request)。 这 个 申 请 需 要 一 个 已 经 包 含 所 有 必 需 的 信 息 的 未 签 署 证 书<br />

( 公 共 部 分 )。 该 证 书 申 请 通 常 发 送 到 认 证 供 应 商 去 签 署 。 这 一 步 同 样 也 在 本 地 机 器 上 创 建 了 私 钥 。<br />

• 证 书 颁 发 机 构 签 署 证 书 。<br />

• 如 果 有 需 要 , 加 入 证 书 和 密 钥 到 单 个 文 件 来 给 应 用 程 序 使 用 (web 服 务 器 、 邮 件 服 务 器 等 )。<br />

11.2 配 置 OpenSSL<br />

我 们 使 用 /usr/local/certs 作 为 这 个 例 子 的 目 录 或 者 根 据 你 的 设 置 相 应 的 编 辑 /etc/ssl/openssl.cnf 文 件 ,<br />

因 此 你 知 道 文 件 将 创 建 在 哪 里 。 以 下 是 openssl.cnf 的 相 关 部 分 :<br />

[ CA_default ]<br />

dir = /usr/local/certs/CA # 保 存 所 有 信 息 的 文 件 夹<br />

certs = $dir/certs # 已 生 成 证 书 的 默 认 保 存 目 录<br />

crl_dir = $dir/crl # 生 成 的 证 书 撤 销 列 表 (CRL) 的 默 认 保 存 目 录<br />

database = $dir/index.txt # 保 存 已 签 发 证 书 的 文 本 数 据 库 文 件<br />

确 保 所 有 目 录 已 经 创 建<br />

# mkdir -p /usr/local/certs/CA<br />

# cd /usr/local/certs/CA<br />

# mkdir certs crl newcerts private<br />

# echo "01" > serial # 仅 当 serial 不 存 在 时<br />

# touch index.txt<br />

11.3 创 建 一 个 认 证 授 权<br />

如 果 你 没 有 来 自 供 应 商 的 认 证 授 权 , 你 必 须 创 建 你 自 己 的 。 如 果 打 算 去 供 应 商 签 署 申 请 , 那 么 这 个 步 骤 不 是 必 须<br />

的 。 创 建 认 证 授 权 (CA):<br />

# openssl req -new -x509 -days 730 -config /etc/ssl/openssl.cnf \<br />

-keyout CA/private/cakey.pem -out CA/cacert.pem<br />

31


— SSL 认 证 —<br />

11.4 创 建 证 书 签 发 申 请<br />

要 创 建 一 个 新 证 书 ( 比 如 给 邮 件 服 务 器 或 web 服 务 器 ), 首 先 用 其 私 钥 创 建 证 书 申 请 。 如 果 你 的 应 用 程 序 不 支 持<br />

加 密 的 私 钥 ( 比 如 UW-IMAP 就 不 支 持 ), 那 么 就 用 -nodes 来 禁 用 加 密 。<br />

# openssl req -new -keyout newkey.pem -out newreq.pem \<br />

-config /etc/ssl/openssl.cnf<br />

# openssl req -nodes -new -keyout newkey.pem -out newreq.pem \<br />

-config /etc/ssl/openssl.cnf<br />

# 不 对 这 个 密 钥 加 密<br />

11.5 签 署 证 书<br />

该 证 书 申 请 由 CA 签 发 确 认 , 这 个 步 骤 通 常 由 供 应 商 完 成 。 注 意 : 在 下 面 命 令 中 替 换 "servername" 成 你 的 服 务<br />

器 名 称 。<br />

# cat newreq.pem newkey.pem > new.pem<br />

# openssl ca -policy policy_anything -out servernamecert.pem \<br />

-config /etc/ssl/openssl.cnf -infiles new.pem<br />

# mv newkey.pem servernamekey.pem<br />

现 在 ,servernamekey.pem 就 是 私 钥 ,servernamecert.pem 就 为 服 务 器 的 证 书 。<br />

11.6 创 建 联 合 认 证 (united certificate)<br />

IMAP 服 务 器 想 要 私 钥 和 服 务 器 证 书 在 同 一 个 文 件 中 。 通 常 , 这 还 是 比 较 容 易 处 理 的 , 但 是 该 文 件 要 保 证 安 全 !<br />

Apache 也 可 以 处 理 好 它 。 创 建 一 个 包 含 证 书 和 密 钥 的 文 件 servername.pem 。<br />

• 用 文 本 编 辑 器 打 开 私 钥 文 件 (servernamekey.pem), 并 拷 贝 私 钥 到 "servername.pem" 文 件 中 去 。<br />

• 服 务 器 证 书 (servernamecert.pem) 也 做 同 样 的 动 作 。<br />

最 后 servername.pem 文 件 应 该 看 起 来 像 这 样 :<br />

-----BEGIN RSA PRIVATE KEY-----<br />

MIICXQIBAAKBgQDutWy+o/XZ/[...]qK5LqQgT3c9dU6fcR+WuSs6aejdEDDqBRQ<br />

-----END RSA PRIVATE KEY-----<br />

-----BEGIN CERTIFICATE-----<br />

MIIERzCCA7CgAwIBAgIBBDANB[...]iG9w0BAQQFADCBxTELMAkGA1UEBhMCREUx<br />

-----END CERTIFICATE-----<br />

现 在 我 们 的 /usr/local/certs/ 目 录 中 有 了 这 些 ;<br />

CA/private/cakey.pem (CA 服 务 器 私 钥 )<br />

CA/cacert.pem (CA 服 务 器 公 钥 )<br />

certs/servernamekey.pem ( 服 务 器 私 钥 )<br />

certs/servernamecert.pem ( 服 务 器 已 签 署 的 证 书 )<br />

certs/servername.pem ( 私 钥 和 服 务 器 证 书 )<br />

要 保 证 私 钥 的 安 全 !<br />

11.7 查 看 证 书 信 息<br />

要 查 看 证 书 信 息 , 只 要 这 么 做 :<br />

# openssl x509 -text -in servernamecert.pem # 显 示 证 书 信 息<br />

# openssl req -noout -text -in server.csr # 显 示 申 请 信 息<br />

# openssl s_client -connect cb.vu:443 # 检 查 web 服 务 器 认 证 信 息<br />

32


12 CVS<br />

服 务 器 设 置 (p33) | CVS 测 试 (p34) | SSH 隧 道 (p34) | CVS 使 用 (p34)<br />

12.1 服 务 器 设 置<br />

CVS 环 境 初 始 化<br />

决 定 主 repository 将 要 创 建 和 重 置 的 cvs 根 目 录 。 比 如 /usr/local/cvs ( 根 ):<br />

# mkdir -p /usr/local/cvs<br />

# setenv CVSROOT /usr/local/cvs # 设 置 CVSROOT 环 境 变 量 ( 本 地 )<br />

# cvs init # 创 建 所 有 初 始 化 CVS 配 置 文 件<br />

# cd /root<br />

# cvs checkout CVSROOT # 签 出 配 置 文 件 来 修 改 他 们<br />

# cd CVSROOT<br />

edit config ( fine as it is)<br />

# cvs commit config<br />

cat >> writers<br />

# 创 建 writers 文 件 ( 也 可 为 readers)<br />

colin<br />

^D<br />

# 使 用 [Control][D] 退 出 编 辑<br />

# cvs add writers # 添 加 文 件 writers 进 repository<br />

# cvs edit checkoutlist<br />

# cat >> checkoutlist<br />

writers<br />

^D<br />

# 使 用 [Control][D] 退 出 编 辑<br />

# cvs commit # 提 交 所 有 配 置 更 改<br />

添 加 一 个 readers 文 件 , 如 果 你 要 区 分 读 写 权 限 的 话 。 注 意 : 不 要 在 主 cvs 中 直 接 编 辑 文 件 , 而 应 该 签 出 要<br />

编 辑 的 文 件 , 修 改 完 成 后 再 签 入 。 我 们 所 做 的 文 件 writers 用 来 定 义 可 写 权 限 。<br />

下 面 有 三 种 流 行 的 方 式 去 访 问 CVS。 前 两 个 不 需 要 任 何 进 一 步 的 配 置 。 看 CVSROOT 部 分 的 实 例 了 解 如 何 使 用 它<br />

们 :<br />

• 直 接 本 的 访 问 文 件 系 统 。 用 户 需 要 有 足 够 的 权 限 来 直 接 访 问 CVS, 除 了 要 登 录 到 操 作 系 统 , 没 有 进 一 步<br />

的 验 证 。 然 而 这 仅 对 本 地 repository 才 有 用 。<br />

• 使 用 ext 协 议 通 过 ssh 来 远 程 访 问 。 任 何 有 ssh shell 账 户 和 在 CVS 服 务 器 上 可 读 写 权 限 的 都 可 直<br />

接 使 用 ext 协 议 通 过 ssh 来 访 问 CVS, 而 不 需 要 任 何 额 外 的 隧 道 。 没 有 服 务 器 来 处 理 运 行 在 CVS 上 的<br />

验 证 工 作 。ssh 登 录 会 去 验 证 。<br />

• 用 pserver 来 远 程 访 问 。 这 是 对 于 有 较 大 用 户 量 的 首 选 方 法 , 用 户 由 CVS 的 pserver 通 过 一 个 专 门 的<br />

密 码 数 据 库 来 验 证 , 因 此 不 需 要 本 地 用 户 帐 户 。 这 种 设 置 在 下 面 会 有 说 明 。<br />

用 inetd 设 置 网 络<br />

如 果 不 需 要 网 络 访 问 ,CVS 可 以 运 行 于 本 地 。 对 于 远 程 访 问 , 在 /etc/inetd.conf (Suse 为 /etc/xinetd.d/<br />

cvs) 中 配 置 如 下 行 , 可 让 守 护 进 程 inetd 启 动 pserver:<br />

cvspserver stream tcp nowait cvs /usr/bin/cvs cvs \<br />

--allow-root=/usr/local/cvs pserver<br />

这 是 个 用 来 阻 断 从 internet 访 问 cvs 端 口 的 好 方 法 , 可 使 用 ssh 隧 道 来 远 程 的 访 问 repository。<br />

单 独 认 证<br />

CVS 用 户 可 能 不 是 操 作 系 统 的 一 部 分 ( 即 不 是 本 地 用 户 )。 这 其 实 可 从 安 全 的 角 度 去 看 。 简 单 的 添 加 一 个 叫<br />

passwd (in the CVSROOT directory) 的 文 件 , 其 包 含 crypt 格 式 的 用 户 登 录 名 和 密 码 。 这 也 可 以 使 用 apache<br />

的 htpasswd 工 具 来 完 成 。<br />

注 意 : 这 个 passwd 文 件 仅 仅 是 文 件 , 可 以 在 CVSROOT 中 直 接 编 辑 。 它 不 能 被 签 出 。 更 多 信 息 请 用 htpasswd<br />

--help<br />

# htpasswd -cb passwd user1 password1 # -c 创 建 文 件<br />

# htpasswd -b passwd user2 password2<br />

— CVS —<br />

现 在 添 加 :cvs 到 每 行 的 结 尾 处 , 用 来 告 诉 cvs 服 务 器 更 改 用 户 到 cvs ( 或 任 何 你 正 在 运 行 的 cvs 服 务 器<br />

下 )。 它 看 起 来 像 这 样 :<br />

33


— CVS —<br />

# cat passwd<br />

user1:xsFjhU22u8Fuo:cvs<br />

user2:vnefJOsnnvToM:cvs<br />

12.2 测 试 它<br />

测 试 作 为 一 般 用 户 登 录 ( 比 如 我 )<br />

# cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs login<br />

Logging in to :pserver:colin@192.168.50.254:2401/usr/local/cvs<br />

CVS password:<br />

CVSROOT 变 量<br />

这 是 个 环 境 变 量 用 来 指 定 repository 的 位 置 。 对 于 本 地 使 用 , 该 变 量 只 需 设 置 成 repository 的 目 录 。 对 于 通<br />

过 网 络 使 用 , 传 输 协 议 必 须 指 定 。 使 用 setenv CVSROOT string (csh, tcsh shell) 或 者 export<br />

CVSROOT=string ( sh, bash shell) 设 置 CVSROOT 环 境 变 量 。<br />

# setenv CVSROOT :pserver:@:/cvsdirectory<br />

For example:<br />

# setenv CVSROOT /usr/local/cvs # 仅 限 本 的 使 用<br />

# setenv CVSROOT :local:/usr/local/cvs # 同 上<br />

# setenv CVSROOT :ext:user@cvsserver:/usr/local/cvs # 通 过 SSH 直 接 访 问<br />

# setenv CVS_RSH ssh # ext 协 议 访 问<br />

# setenv CVSROOT :pserver:user@cvsserver.254:/usr/local/cvs # 通 过 pserver 网 络 访 问<br />

一 旦 登 录 成 功 就 可 导 入 一 个 新 项 目 进 repository:cd 进 入 你 的 项 目 根 目 录<br />

cvs import <br />

cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs import MyProject MyCompany START<br />

在 repository 中 有 个 名 叫 MyProject 新 项 目 ( 之 后 用 来 签 出 )。CVS 会 导 入 当 前 目 录 的 内 容 进 新 项 目 。<br />

签 出 :<br />

# cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs checkout MyProject<br />

或 者<br />

# setenv CVSROOT :pserver:colin@192.168.50.254:/usr/local/cvs<br />

# cvs checkout MyProject<br />

12.3 通 过 SSH 隧 道 访 问 CVS<br />

我 们 需 要 两 个 shell 来 做 这 个 。 在 第 一 个 shell 中 , 我 们 连 接 到 cvs 服 务 器 并 对 cvs 连 接 进 行 端 口 转 发<br />

(port-forward)。 在 第 二 个 shell 中 , 我 们 就 像 在 本 地 一 样 使 用 cvs。<br />

在 shell 1:<br />

# ssh -L2401:localhost:2401 colin@cvs_server # 直 接 连 接 到 cvs 服 务 器 。 或 :<br />

# ssh -L2401:cvs_server:2401 colin@gateway # 使 用 一 个 网 关 间 接 连 接 到 cvs 服 务 器<br />

在 shell 2:<br />

# setenv CVSROOT :pserver:colin@localhost:/usr/local/cvs<br />

# cvs login<br />

Logging in to :pserver:colin@localhost:2401/usr/local/cvs<br />

CVS password:<br />

# cvs checkout MyProject/src<br />

12.4 CVS 命 令 及 其 使 用<br />

导 入<br />

该 import 命 令 用 来 添 加 整 个 目 录 , 它 必 须 运 行 于 要 导 入 的 目 录 中 。 比 如 , 目 录 /devel/ 包 含 的 所 有 文 件 和 子<br />

目 录 要 导 入 。 该 目 录 名 在 CVS 中 ( 模 块 ) 将 会 称 为 "myapp"。<br />

34


# cvs import [options] directory-name vendor-tag release-tag<br />

# cd /devel # 必 须 在 该 目 录 中 来 导 入<br />

# cvs import myapp Company R1_0 # 修 订 (release) 标 签 可 以 为 任 何 单 个 单 词<br />

在 添 加 了 一 个 新 目 录 "/devel/tools/" 后 , 也 可 这 么 导 入 。<br />

# cd /devel/tools<br />

# cvs import myapp/tools Company R1_0<br />

签 出 、 更 新 和 提 交<br />

# cvs co myapp/tools # 仅 会 签 出 tools 目 录<br />

# cvs co -r R1_1 myapp # 签 出 修 订 版 本 为 R1_1 的 myapp (sticky)<br />

# cvs -q -d update -P # 典 型 的 CVS 更 新<br />

# cvs update -A # 重 置 所 有 sticky 标 签 ( 或 日 期 、 选 项 )<br />

# cvs add newfile # 添 加 一 个 新 文 件<br />

# cvs add -kb newfile # 添 加 一 个 二 进 制 文 件<br />

# cvs commit file1 file2 # 仅 提 交 这 两 个 文 件<br />

# cvs commit -m "message" # 提 交 所 有 更 改 并 为 这 个 更 改 添 加 日 志 消 息<br />

创 建 一 个 patch<br />

It is best to create and apply a patch from the working development directory related to the<br />

project, or from within the source directory.<br />

# cd /devel/project<br />

# diff -Naur olddir newdir > patchfile # Create a patch from a directory or a file<br />

# diff -Naur oldfile newfile > patchfile<br />

应 用 一 个 patch<br />

Sometimes it is necessary to strip a directory level from the patch, depending how it was created.<br />

In case of difficulties, simply look at the first lines of the patch and try -p0, -p1 or -p2.<br />

# cd /devel/project<br />

# patch --dry-run -p0 < patchfile # Test the path without applying it<br />

# patch -p0 < patchfile<br />

# patch -p1 < patchfile # strip off the 1st level from the path<br />

13 SVN<br />

Server setup (p35) | SVN+SSH (p36) | SVN over http (p36) | SVN usage (p36)<br />

Subversion (SVN) 34 is a version control system designed to be the successor of CVS (Concurrent<br />

Versions System). The concept is similar to CVS, but many shortcomings where improved. See also<br />

the SVN book 35 .<br />

13.1 Server setup<br />

The initiation of the repository is fairly simple (here for example /home/svn/ must exist):<br />

# svnadmin create --fs-type fsfs /home/svn/project1<br />

— SVN —<br />

Now the access to the repository is made possible with:<br />

• file:// Direct file system access with the svn client with. This requires local permissions<br />

on the file system.<br />

• svn:// or svn+ssh:// Remote access with the svnserve server (also over SSH). This requires<br />

local permissions on the file system.<br />

• http:// Remote access with webdav using apache. No local users are necessary for this<br />

method.<br />

34.http://subversion.tigris.org/<br />

35.http://svnbook.red-bean.com/en/1.4/<br />

35


Using the local file system, it is now possible to import and then check out an existing project.<br />

Unlike with CVS it is not necessary to cd into the project directory, simply give the full path:<br />

# svn import /project1/ file:///home/svn/project1/trunk -m 'Initial import'<br />

# svn checkout file:///home/svn/project1<br />

The new directory "trunk" is only a convention, this is not required.<br />

Remote access with ssh<br />

No special setup is required to access the repository via ssh, simply replace file:// with<br />

svn+ssh/hostname. For example:<br />

# svn checkout svn+ssh://hostname/home/svn/project1<br />

As with the local file access, every user needs an ssh access to the server (with a local account)<br />

and also read/write access. This method might be suitable for a small group. All users could<br />

belong to a subversion group which owns the repository, for example:<br />

# groupadd subversion<br />

# groupmod -A user1 subversion<br />

# chown -R root:subversion /home/svn<br />

# chmod -R 770 /home/svn<br />

Remote access with http (apache)<br />

Remote access over http (https) is the only good solution for a larger user group. This method<br />

uses the apache authentication, not the local accounts. This is a typical but small apache<br />

configuration:<br />

LoadModule dav_module modules/mod_dav.so<br />

LoadModule dav_svn_module modules/mod_dav_svn.so<br />

LoadModule authz_svn_module modules/mod_authz_svn.so # Only for access control<br />

<br />

DAV svn<br />

# any "/svn/foo" URL will map to a repository /home/svn/foo<br />

SVNParentPath /home/svn<br />

AuthType Basic<br />

AuthName "Subversion repository"<br />

AuthzSVNAccessFile /etc/apache2/svn.acl<br />

AuthUserFile /etc/apache2/svn-passwd<br />

Require valid-user<br />

<br />

The apache server needs full access to the repository:<br />

# chown -R www:www /home/svn<br />

Create a user with htpasswd2:<br />

# htpasswd -c /etc/svn-passwd user1 # -c creates the file<br />

Access control svn.acl example<br />

# Default it read access. "* =" would be default no access<br />

[/]<br />

* = r<br />

[groups]<br />

project1-developers = joe, jack, jane<br />

# Give write access to the developers<br />

[project1:]<br />

@project1-developers = rw<br />

13.2 SVN commands and usage<br />

— SVN —<br />

See also the Subversion Quick Reference Card 36 . Tortoise SVN 37<br />

is a nice Windows interface.<br />

36


— 实 用 命 令 —<br />

Import<br />

A new project, that is a directory with some files, is imported into the repository with the<br />

import command. Import is also used to add a directory with its content to an existing project.<br />

# svn help import # Get help for any command<br />

# Add a new directory (with content) into the src dir on project1<br />

# svn import /project1/newdir http://host.url/svn/project1/trunk/src -m 'add newdir'<br />

Typical SVN commands<br />

# svn co http://host.url/svn/project1/trunk # Checkout the most recent version<br />

# Tags and branches are created by copying<br />

# svn mkdir http://host.url/svn/project1/tags/ # Create the tags directory<br />

# svn copy -m "Tag rc1 rel." http://host.url/svn/project1/trunk \<br />

http://host.url/svn/project1/tags/1.0rc1<br />

# svn status [--verbose] # Check files status into working dir<br />

# svn add src/file.h src/file.cpp # Add two files<br />

# svn commit -m 'Added new class file' # Commit the changes with a message<br />

# svn ls http://host.url/svn/project1/tags/ # List all tags<br />

# svn move foo.c bar.c # Move (rename) files<br />

# svn delete some_old_file # Delete files<br />

14 实 用 命 令<br />

less (p37) | vi (p37) | mail (p38) | tar (p38) | dd (p39) | screen (p40) | find (p40) | 混 杂 的<br />

(p41)<br />

14.1 less<br />

less 命 令 用 来 在 控 制 台 中 分 屏 显 示 文 本 文 档 。 它 在 许 多 发 行 版 中 可 用 。<br />

# less unixtoolbox.xhtml<br />

一 些 重 要 指 令 (^N 代 表 [control]-[N]):<br />

h H 显 示 指 令 的 汇 总 列 表<br />

f ^F ^V SPACE 向 前 滚 动 一 屏 ( 或 者 N 行 )<br />

b ^B ESC-v 向 后 滚 动 一 屏 ( 或 者 N 行 )<br />

F 向 前 滚 动 ; 类 似 于 "tail -f"<br />

/pattern 向 前 搜 索 匹 配 该 模 式 的 行<br />

?pattern 向 后 搜 索 匹 配 该 模 式 的 行<br />

n 重 复 之 前 的 搜 索<br />

N 反 方 向 重 复 之 前 的 搜 索<br />

q 退 出<br />

14.2 vi<br />

Vi 在 任 何 Linux/<strong>Unix</strong> 发 行 安 装 版 (gentoo 没 有 ?) 上 都 存 在 。 因 此 , 我 们 有 必 要 了 解 一 些 基 本 的 命 令 。Vi 有 两<br />

个 模 式 : 命 令 模 式 和 插 入 模 式 。 使 用 [ESC] 键 可 进 入 命 令 模 式 , 使 用 i 键 可 进 入 插 入 模 式 。 如 果 你 迷 失 了 , 可<br />

在 命 令 模 式 下 键 入 : help。<br />

编 辑 器 nano 和 pico 通 常 也 都 可 用 , 而 且 更 容 易 (IMHO) 使 用 。<br />

Quit<br />

:w newfilename 保 存 文 件 为 newfilename<br />

:wq or :x 保 存 并 退 出<br />

:q! 退 出 但 不 保 存<br />

36.http://www.cs.put.poznan.pl/csobaniec/Papers/svn-refcard.pdf<br />

37.http://tortoisesvn.tigris.org<br />

37


— 实 用 命 令 —<br />

移 动 和 查 找<br />

/string 向 前 查 找 string<br />

?string 向 后 查 找 string<br />

n 同 方 向 重 复 上 一 次 搜 索 命 令<br />

N 反 方 向 重 复 上 一 次 搜 索 命 令<br />

{ 光 标 移 至 段 落 结 尾<br />

} 光 标 移 至 段 落 开 头<br />

1G 光 标 移 至 文 件 的 第 一 行 首<br />

nG 光 标 移 至 文 件 的 第 n 行 首<br />

G 光 标 移 至 文 件 的 最 后 一 行 首<br />

:%s/OLD/NEW/g 替 换 所 有 查 找 到 的 OLD 为 NEW<br />

删 除 文 本<br />

dd<br />

D<br />

dw<br />

x<br />

u<br />

U<br />

删 除 当 前 行<br />

删 除 光 标 到 当 前 行 末 尾 的 字 符<br />

删 除 单 词<br />

删 除 字 符<br />

回 复 上 一 次 操 作<br />

回 复 所 有 此 行 的 更 改<br />

14.3 mail<br />

mail 命 令 是 一 个 读 取 和 发 送 邮 件 的 应 用 程 序 , 她 通 常 已 安 装 。 要 发 送 一 封 邮 件 , 可 以 简 单 的 输 入 "mail<br />

user@domain"。 其 第 一 行 为 主 题 , 然 后 是 邮 件 内 容 。 在 一 个 新 行 中 使 用 单 个 点 (.) 来 结 束 并 发 送 邮 件 。 例 子 :<br />

# mail c@cb.vu<br />

Subject: Your text is full of typos<br />

"For a moment, nothing happened. Then, after a second or so,<br />

nothing continued to happen."<br />

.<br />

EOT<br />

#<br />

这 同 样 可 用 于 管 道 :<br />

# echo "This is the mail body" | mail c@cb.vu<br />

也 是 测 试 邮 件 服 务 器 的 简 单 方 法 。<br />

14.4 tar<br />

命 令 tar ( 磁 带 存 档 ) 可 以 为 文 件 和 目 录 创 建 档 案 。 归 档 文 件 .tar 是 未 压 缩 的 , 一 个 压 缩 过 的 归 档 文 件 的 后 缀<br />

是 .tgz 或 .tar.gz (zip) 或 者 .tbz (bzip2)。 不 要 使 用 绝 对 路 径 建 立 一 个 归 档 文 件 , 你 可 能 要 解 开 这 个 归 档<br />

文 件 到 某 个 地 方 。 一 些 常 用 命 令 如 下 :<br />

创 建<br />

# cd /<br />

# tar -cf home.tar home/ # 归 档 整 个 /home 目 录 (c 为 创 建 )<br />

# tar -czf home.tgz home/ # 等 同 于 zip 压 缩<br />

# tar -cjf home.tbz home/ # 等 同 于 bzip2 压 缩<br />

从 一 个 目 录 树 中 只 包 含 一 个 ( 或 2 个 ) 目 录 , 并 保 持 相 对 目 录 结 构 。 举 个 例 子 ,/usr/local/etc 和 /usr/local/<br />

www, 它 们 在 归 档 文 件 中 的 第 一 层 目 录 是 local/。<br />

# tar -C /usr -czf local.tgz local/etc local/www<br />

# tar -C /usr -xzf local.tgz # 释 放 local 目 录 到 /usr<br />

# cd /usr; tar -xzf local.tgz # 同 上 面 一 样<br />

38


— 实 用 命 令 —<br />

释 放 (Extract)<br />

# tar -tzf home.tgz # 列 出 归 档 文 件 中 的 所 有 文 件 , 并 不 释 放<br />

# tar -xf home.tar # 释 放 归 档 文 件 (x 为 释 放 )<br />

# tar -xzf home.tgz # 等 同 于 zip 压 缩<br />

# tar -xjf home.tgz # 等 同 于 bzip2 压 缩<br />

# tar -xjf home.tgz home/colin/file.txt # 释 放 单 个 文 件<br />

更 高 级 的<br />

# tar c dir/ | gzip | ssh user@remote 'dd of=dir.tgz' # 归 档 压 缩 dir/ 目 录 并 存 储 到 远 程 主 机 上<br />

# tar cvf - `find . -print` > backup.tar # 归 档 当 前 目 录<br />

# tar -cf - -C /etc . | tar xpf - -C /backup/etc # 拷 贝 目 录<br />

# tar -cf - -C /etc . | ssh user@remote tar xpf - -C /backup/etc # 远 程 拷 贝<br />

# tar -czf home.tgz --exclude '*.o' --exclude 'tmp/' home/<br />

14.5 dd<br />

程 序 dd ( 磁 盘 备 份 (disk dump) 或 destroy disk, 也 可 看 dd 的 含 义 ) 用 来 拷 贝 分 区 、 磁 盘 或 者 其 它 拷 贝 。 通<br />

常 这 么 用 :<br />

# dd if= of= bs= conv=<br />

重 要 的 conv 选 项 :<br />

notrunc 不 截 短 输 出 文 件<br />

noerror 出 错 时 不 停 止 处 理 (e.g. 坏 扇 区 )<br />

sync 把 每 个 输 入 块 填 充 到 ibs 个 字 节 , 不 足 部 分 用 空 (NUL) 字 符 补 齐<br />

默 认 字 节 大 小 为 512 ( 一 个 扇 区 )。MBR 处 于 磁 盘 的 第 一 个 扇 区 , 之 后 的 63 个 扇 区 是 空 的 。 较 大 的 字 节 大 小 可<br />

以 加 快 拷 贝 速 度 但 也 需 要 更 多 的 内 存 。<br />

备 份 和 恢 复<br />

# dd if=/dev/hda of=/dev/hdc bs=16065b # 拷 贝 磁 盘 到 磁 盘 ( 相 同 大 小 )<br />

# dd if=/dev/sda7 of /home/root.img bs=4096 conv=notrunc,noerror # 备 份 /<br />

# dd if /home/root.img of=/dev/sda7 bs=4096 conv=notrunc,noerror # 恢 复 /<br />

# dd bs=1M if=/dev/ad4s3e | gzip -c > ad4s3e.gz # 压 缩 备 份<br />

# gunzip -dc ad4s3e.gz | dd of=/dev/ad0s3e bs=1M # 解 压 恢 复<br />

# dd bs=1M if=/dev/ad4s3e | gzip | ssh eedcoba@fry 'dd of=ad4s3e.gz' # 也 可 为 远 程 的<br />

# gunzip -dc ad4s3e.gz | ssh eedcoba@host 'dd of=/dev/ad0s3e bs=1M'<br />

# dd if=/dev/ad0 of=/dev/ad2 skip=1 seek=1 bs=4k conv=noerror # 忽 略 MBR<br />

# 如 果 目 标 (ad2) 比 较 小 , 这 是 必 须 的 。<br />

恢 复<br />

该 dd 命 令 会 读 取 分 区 的 每 一 个 区 块 , 即 所 有 区 块 。 对 于 有 问 题 的 区 块 , 最 好 使 用 conv=sync,noerror 选 项 ,<br />

dd 将 会 跳 过 坏 的 区 块 并 入 0。 因 此 , 这 就 是 设 置 块 大 小 等 于 或 小 于 磁 盘 块 大 小 的 重 要 性 。1k 大 小 似 乎 安 全 , 用<br />

bs=1k 来 设 置 它 。 假 如 一 个 磁 盘 有 坏 扇 区 并 且 有 个 分 区 的 数 据 要 恢 复 , 那 么 用 dd 工 具 创 建 一 个 镜 像 文 件 , 挂 载<br />

这 个 镜 像 文 件 , 然 后 拷 贝 内 容 到 新 的 磁 盘 中 。 如 果 用 了 noerror 选 项 ,dd 会 跳 过 坏 扇 区 并 写 入 0, 也 即 坏 扇 区<br />

中 的 内 容 会 丢 失 。<br />

# dd if=/dev/hda of=/dev/null bs=1m # 检 查 坏 扇 区<br />

# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc | gzip | ssh \ # 发 送 到 远 程<br />

root@fry 'dd of=hda1.gz bs=1k'<br />

# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc of=hda1.img # 存 储 为 一 个 映 像 文 件<br />

# mount -o loop /hda1.img /mnt # 挂 载 这 个 映 像 文 件 (page 13)<br />

# rsync -ax /mnt/ /newdisk/ # 拷 贝 到 一 个 新 磁 盘<br />

# dd if=/dev/hda of=/dev/hda # 刷 新 磁 状 态<br />

# 上 面 的 命 令 对 于 刷 新 磁 盘 (refresh disk) 很 有 用 。 这 绝 对 安 全 , 但 必 须 先 卸 载 磁 盘 。<br />

39


— 实 用 命 令 —<br />

删 除<br />

# dd if=/dev/zero of=/dev/hdc # 删 除 全 部 数 据<br />

# dd if=/dev/urandom of=/dev/hdc<br />

38<br />

# 更 好 的 删 除 全 部 数 据<br />

# kill -USR1 PID # 查 看 dd 进 度 ( 仅 Linux!)<br />

MBR 技 巧<br />

MBR 包 含 了 引 导 程 序 和 分 区 表 , 它 的 大 小 为 512 字 节 。 前 446 字 节 为 引 导 程 序 ,446 到 512 字 节 为 分 区 表 。<br />

# dd if=/dev/sda of=/mbr_sda.bak bs=512 count=1 # 完 全 备 份 MBR<br />

# dd if=/dev/zero of=/dev/sda bs=512 count=1 # 删 除 MBR 和 分 区 表<br />

# dd if=/mbr_sda.bak of=/dev/sda bs=512 count=1 # 完 全 恢 复 MBR<br />

# dd if=/mbr_sda.bak of=/dev/sda bs=446 count=1 # 仅 回 复 引 导 程 序<br />

# dd if=/mbr_sda.bak of=/dev/sda bs=1 count=64 skip=446 seek=446 # 恢 复 分 区 表<br />

14.6 screen<br />

Screen 提 供 了 两 个 主 要 功 能 :<br />

• 在 一 个 终 端 内 运 行 多 个 终 端 会 话 (terminal session)。<br />

• 一 个 已 启 动 的 程 序 与 运 行 它 的 真 实 终 端 分 离 的 , 因 此 可 运 行 于 后 台 。 真 实 的 终 端 可 以 被 关 闭 , 还 可 以 在<br />

稍 后 再 重 新 接 上 (reattached)。<br />

简 短 实 例<br />

开 启 screen:<br />

# screen<br />

在 screen 会 话 中 , 我 们 可 以 开 启 一 个 长 时 间 运 行 的 程 序 ( 如 top)。Detach 这 个 终 端 , 之 后 可 以 从 其 他 机 器<br />

reattach 这 个 相 同 的 终 端 ( 比 如 通 过 ssh)。<br />

# top<br />

现 在 用 Ctrl-a Ctrl-d 来 detach。Reattach 终 端 :<br />

# screen -r<br />

或 更 好 的 :<br />

# screen -R -D<br />

现 在 attach 到 这 里 。 具 体 意 思 是 : 先 试 图 恢 复 离 线 的 screen 会 话 。 若 找 不 到 离 线 的 screen 会 话 , 即 建 立 新<br />

的 screen 会 话 给 用 户 。<br />

Screen 命 令 ( 在 screen 中 )<br />

所 有 命 令 都 以 Ctrl-a 开 始 。<br />

• Ctrl-a ? 各 功 能 的 帮 助 摘 要<br />

• Ctrl-a c 创 建 一 个 新 的 window ( 终 端 )<br />

• Ctrl-a Ctrl-n 和 Ctrl-a Ctrl-p 切 换 到 下 一 个 或 前 一 个 window<br />

• Ctrl-a Ctrl-N N 为 0 到 9 的 数 字 , 用 来 切 换 到 相 对 应 的 window<br />

• Ctrl-a " 获 取 所 有 正 在 运 行 的 window 的 可 导 航 的 列 表<br />

• Ctrl-a a 清 楚 错 误 的 Ctrl-a<br />

• Ctrl-a Ctrl-d 断 开 所 有 会 话 , 会 话 中 所 有 任 务 运 行 于 后 台<br />

• Ctrl-a x 用 密 码 锁 柱 screen 终 端<br />

当 程 序 内 部 运 行 终 端 关 闭 并 且 你 登 出 该 终 端 时 , 该 screen 会 话 就 会 被 终 止 。<br />

14.7 Find<br />

一 些 重 要 选 项 :<br />

-x (BSD) -xdev (Linux) 留 于 同 一 文 件 系 统 (fstab 中 的 dev)<br />

-exec cmd {} \; 执 行 命 令 并 用 全 路 径 替 换 {}<br />

38. 译 注 :/dev/urandom 设 备 文 件 提 供 了 一 种 比 单 独 使 用 $RANDOM 更 好 的 , 能 产 生 更 " 随 机 " 的 随 机 数 的 方 法 。<br />

40


-iname 同 -name 一 样 , 但 不 区 分 大 小 写<br />

-ls 显 示 关 于 文 件 的 信 息 ( 同 ls -la)<br />

-size n n 为 +-n (k M G T P)<br />

-cmin n 查 找 系 统 中 最 后 n 分 钟 改 变 文 件 状 态 的 文 件<br />

# find . -type f ! -perm -444 # 寻 找 所 有 无 法 读 取 的 文 件<br />

# find . -type d ! -perm -111 # 寻 找 所 有 无 法 访 问 的 目 录<br />

# find /home/user/ -cmin 10 -print # 寻 找 最 后 10 分 钟 创 建 或 修 改 的 文 件<br />

# find . -name '*.[ch]' | xargs grep -E 'expr' # 在 当 前 目 录 及 子 目 录 搜 索 'expr' 表 达 式<br />

# find / -name "*.core" | xargs rm # 寻 找 core 垃 圾 并 删 除 它 们 ( 也 可 试 试 core.*)<br />

# find / -name "*.core" -print -exec rm {} \; # 另 一 种 语 法<br />

# 寻 找 图 像 文 件 并 创 建 一 个 归 档 文 件 ,iname 为 不 区 分 大 小 写 。-r 为 附 加<br />

# find . \( -iname "*.png" -o -iname "*.jpg" \) -print -exec tar -rf images.tar {} \;<br />

# find . -type f -name "*.txt" ! -name README.txt -print # 除 README.txt 的 文 件<br />

# find /var/ -size +10M -exec ls -lh {} \; # 查 找 > 10 MB 的 文 件<br />

# find /var/ -size +10M -ls # 这 个 更 简 单<br />

# find . -size +10M -size -50M -print<br />

# find /usr/ports/ -name work -type d -print -exec rm -rf {} \; # 清 理 port<br />

# 以 SUID 查 找 文 件 ; 这 些 文 件 很 脆 弱 , 必 须 保 持 安 全 。<br />

# find / -type f -user root -perm -4000 -exec ls -l {} \;<br />

小 心 xarg 或 exec, 因 为 当 文 件 或 目 录 中 包 含 空 格 时 可 能 会 返 回 错 误 的 结 果 。 在 有 疑 惑 时 用 "-print0 | xargs<br />

-0" 代 替 "| xargs"。 选 项 -print0 必 须 在 find 命 令 的 最 后 。 看 这 个 不 错 的 find 迷 你 教 程<br />

39<br />

.<br />

# find . -type f | xargs ls -l # 不 能 工 作 于 有 空 格 的 名 字<br />

# find . -type f -print0 | xargs -0 ls -l # 可 工 作 于 有 空 格 的 名 字<br />

# find . -type f -exec ls -l '{}' \; # 或 使 用 用 于 -exec 的 引 用 '{}'<br />

14.8 混 杂 的<br />

— 软 件 安 装 —<br />

# which command # 显 示 命 令 的 全 路 径 名<br />

# time command # 显 示 一 个 命 令 执 行 完 成 所 用 的 时 间<br />

# time cat # 使 用 time 作 为 秒 表 , 用 Ctrl-c 来 停 止<br />

# set | grep $USER # 列 显 当 前 环 境 变 量<br />

# cal -3 # 显 示 三 个 月 日 历<br />

# date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]<br />

# date 10022155 # 设 置 日 期 和 时 间<br />

# whatis grep # 显 示 命 令 的 简 短 信 息<br />

# whereis java # 查 询 命 令 的 的 路 径 和 标 准 目 录<br />

# setenv varname value # 设 置 环 境 变 量 , 设 置 变 量 varname 的 值 为 value (csh/tcsh)<br />

# export varname="value" # 设 置 环 境 变 量 , 设 置 变 量 varname 的 值 为 value (sh/ksh/bash)<br />

# pwd # 显 示 当 前 工 作 目 录<br />

# mkdir -p /path/to/dir # 如 果 存 在 不 显 示 错 误 , 建 立 所 需 的 上 级 目 录<br />

# mkdir -p project/{bin,src,obj,doc/{html,man,pdf},debug/some/more/dirs}<br />

# rmdir /path/to/dir # 移 除 目 录<br />

# rm -rf /path/to/dir # 移 除 目 录 和 其 内 容 ( 强 制 )<br />

# cp -la /dir1 /dir2 # 存 档 、 硬 连 接 目 录 所 有 文 件 , 用 来 替 代 拷 贝<br />

# cp -lpR /dir1 /dir2 # 同 上 (FreeBSD)<br />

# cp unixtoolbox.xhtml{,.bak} # 拷 贝 文 件 成 新 扩 展 名 的 快 速 方 法<br />

# mv /dir1 /dir2 # 修 改 目 录 名<br />

15 软 件 安 装<br />

15.1 列 出 已 安 装 过 的 软 件 包<br />

# rpm -qa # 列 出 已 安 装 过 的 软 件 包 (RH, SuSE, 基 于 RPM 的 )<br />

# dpkg -l # Debian, Ubuntu<br />

# pkg_info # 列 出 所 有 已 安 装 过 的 软 件 包 (FreeBSD)<br />

# pkg_info -W smbd # 查 看 smbd 安 装 了 那 些 软 件 包 (FreeBSD)<br />

# pkginfo # Solaris<br />

39.http://www.hccfl.edu/pollock/<strong>Unix</strong>/FindCmd.htm<br />

41


— 软 件 安 装 —<br />

15.2 添 加 / 删 除 软 件<br />

前 端 界 面 :SuSE 为 yast2/yast,Red Hat 为 redhat-config-packages。<br />

# rpm -i pkgname.rpm # 安 装 软 件 包 (RH, SuSE, 基 于 RPM 的 )<br />

# rpm -e pkgname # 删 除 软 件 包<br />

Debian<br />

# apt-get update # 更 新 源 列 表<br />

# apt-get install emacs # 安 装 emacs 软 件 包<br />

# dpkg --remove emacs # 删 除 emacs 软 件 包<br />

# dpkg -S file # 查 找 拥 有 该 file 的 软 件 包<br />

Gentoo<br />

Gentoo 使 用 emerge 作 为 "Portage" 软 件 包 管 理 系 统 的 核 心 。<br />

# emerge --sync # 同 步 更 新 本 地 protage 树<br />

# emerge -u packagename # 安 装 或 更 新 一 个 软 件 包<br />

# emerge -C packagename # 删 除 软 件 包<br />

# revdep-rebuild # 修 复 依 赖 关 系 的 缺 失<br />

Solaris<br />

路 径 通 常 为 /cdrom/cdrom0.<br />

# pkgadd -d /Solaris_9/Product SUNWgtar<br />

# pkgadd -d SUNWgtar # 添 加 下 载 的 软 件 包 ( 先 要 bunzip2)<br />

# pkgrm SUNWgtar # 删 除 软 件 包<br />

FreeBSD<br />

# pkg_add -r rsync # 获 取 并 安 装 rsync<br />

# pkg_delete /var/db/pkg/rsync-xx # 删 除 rsync 软 件 包<br />

可 使 用 PACKAGESITE 环 境 变 量 来 设 置 哪 里 可 以 获 取 软 件 包 。 举 个 例 子 :<br />

# export PACKAGESITE=ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/Latest/<br />

# or ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-6-stable/Latest/<br />

FreeBSD ports<br />

Port 树 /usr/ports/ 是 一 个 准 备 编 译 和 安 装 的 软 件 集 。 可 用 portsnap 工 具 来 跟 新 port。<br />

# portsnap fetch extract # 当 第 一 次 运 行 这 个 命 令 , 会 创 建 port 树<br />

# portsnap fetch update # 跟 新 port 树<br />

# cd /usr/ports/net/rsync/ # 选 择 软 件 安 装 目 录<br />

# make install distclean # 安 装 并 清 理 ( 也 可 看 man ports)<br />

# make package # Make 一 个 二 进 制 软 件 包<br />

15.3 库 路 径<br />

由 于 复 杂 的 依 赖 关 系 和 运 行 时 链 接 , 程 序 难 于 分 发 或 拷 贝 到 其 他 系 统 。 不 过 对 于 较 少 依 赖 关 系 的 小 程 序 , 缺 失 的<br />

库 可 被 拷 贝 过 去 。 运 行 时 库 ( 即 缺 失 的 库 ) 可 用 ldd 和 ldconfig 来 检 查 和 管 理 。<br />

# ldd /usr/bin/rsync # 列 出 所 有 所 需 的 运 行 时 库<br />

# ldconfig -n /path/to/libs/ # 添 加 一 个 路 径 到 共 享 库 目 录 Add a path to the shared libraries directories<br />

# ldconfig -m /path/to/libs/ # FreeBSD<br />

# LD_LIBRARY_PATH # 设 置 连 接 库 路 径 的 环 境 变 量<br />

42


16 媒 体 转 换<br />

— 媒 体 转 换 —<br />

有 时 候 需 要 转 换 一 个 视 频 、 音 频 文 件 或 者 文 档 成 其 他 格 式 。<br />

16.1 文 本 编 码<br />

文 本 编 码 可 以 得 到 完 全 错 误 的 , 特 别 是 当 语 言 需 要 某 些 特 殊 字 符 像 àäç。 命 令 iconv 可 以 从 一 个 编 码 转 换 成 另<br />

一 个 编 码 。<br />

# iconv -f -t <br />

# iconv -f ISO8859-1 -t UTF-8 -o file.input > file_utf8<br />

# iconv -l # 列 显 系 统 所 支 持 的 字 符 编 码<br />

若 文 档 显 示 良 好 , 通 常 都 可 不 使 用 -f 选 项 ,iconv 会 使 用 本 地 字 符 集 (char-set)。<br />

16.2 <strong>Unix</strong> - DOS 新 行<br />

在 <strong>Unix</strong> Shell 中 转 换 DOS (CR/LF) 到 <strong>Unix</strong> (LF) 新 行 格 式 。 也 可 使 用 dos2unix 和 unix2dos 工 具 , 如 果 你<br />

有 它 们 的 话 。<br />

# sed 's/.$//' dosfile.txt > unixfile.txt<br />

在 Windows 环 境 中 转 换 <strong>Unix</strong> 到 Dos 新 行 格 式 。 需 要 在 mingw 或 cygwin 中 使 用 sed。<br />

# sed -n p unixfile.txt > dosfile.txt<br />

16.3 PDF 转 换 成 Jpeg 和 连 接 一 串 PDF 文 件<br />

用 gs (GhostScript) 工 具 转 换 PDF 文 档 的 每 一 页 成 jpeg ( 或 png) 图 像 。 也 可 以 使 用 更 短 的 convert ( 来 自<br />

ImageMagick 或 GraphicsMagick 工 具 ) 命 令 。<br />

# gs -dBATCH -dNOPAUSE -sDEVICE=jpeg -r150 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \<br />

-dMaxStripSize=8192 -sOutputFile=unixtoolbox_%d.jpg unixtoolbox.pdf<br />

# convert unixtoolbox.pdf unixtoolbox-%03d.png<br />

# convert *.jpeg images.pdf # 把 所 有 图 片 转 换 成 一 份 简 单 的 PDF 文 档<br />

Ghostscript 同 样 可 连 接 多 个 pdf 文 件 成 一 份 PDF 文 档 。 这 仅 可 工 作 于 这 些 PDF 文 件 都 " 呈 现 一 致 (well<br />

behaved)" 的 情 况 下 。<br />

# gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=all.pdf \<br />

file1.pdf file2.pdf ...<br />

# 在 Windows 上 使 用 '#' 代 替 '='<br />

16.4 视 频 转 换<br />

使 用 mpeg4 编 码 压 缩 佳 能 数 码 相 机 视 频 并 修 复 无 用 音 质 。<br />

# mencoder -o videoout.avi -oac mp3lame -ovc lavc -srate 11025 \<br />

-channels 1 -af-adv force=1 -lameopts preset=medium -lavcopts \<br />

vcodec=msmpeg4v2:vbitrate=600 -mc 0 vidoein.AVI<br />

对 于 声 音 的 处 理 可 看 sox。<br />

16.5 拷 贝 音 频 光 盘<br />

程 序 cdparanoia 40 可 以 保 存 音 轨 (FreeBSD port 在 audio/cdparanoia/),oggenc 可 编 码 Ogg Vorbis 格<br />

式 ,lame 可 转 换 成 mp3。<br />

# cdparanoia -B # 拷 贝 音 轨 成 wav 文 件 到 当 前 目 录 列 表 (dir)<br />

# lame -b 256 in.wav out.mp3 # 编 码 成 256 kb/s 的 mp3<br />

# for i in *.wav; do lame -b 256 $i `basename $i .wav`.mp3; done<br />

# oggenc in.wav -b 256 out.ogg # 编 码 成 256 kb/s 的 Ogg Vorbis<br />

40.http://xiph.org/paranoia/<br />

43


17 打 印<br />

— 打 印 —<br />

17.1 打 印 命 令 lpr<br />

# lpr unixtoolbox.ps # 用 默 认 打 印 机 打 印<br />

# export PRINTER=hp4600 # 更 改 默 认 打 印 机<br />

# lpr -Php4500 #2 unixtoolbox.ps # 指 定 打 印 机 hp4500 并 打 印 2 份<br />

# lpr -o Duplex=DuplexNoTumble ... # 启 用 双 面 打 印<br />

# lpr -o PageSize=A4,Duplex=DuplexNoTumble ...<br />

# lpq # 查 看 默 认 打 印 机 的 队 列<br />

# lpq -l -Php4500 # 详 细 显 示 打 印 机 队 列 信 息<br />

# lprm - # 删 除 所 有 打 印 机 内 的 用 户 打 印 作 业<br />

# lprm -Php4500 3186 # 删 除 作 业 3186。 可 使 用 lpq 查 看 作 业 号<br />

# lpc status # 列 印 所 有 可 用 打 印 机<br />

# lpc status hp4500 # 如 果 打 印 机 在 线 , 查 看 其 状 态 和 列 队 长 度<br />

当 要 打 印 PDF 文 件 时 , 一 些 打 印 设 备 不 具 备 处 理 postscript 的 能 力 。 可 以 这 样 解 决<br />

41<br />

:<br />

# gs -dSAFER -dNOPAUSE -sDEVICE=deskjet -sOutputFile=\|lpr file.pdf<br />

18 数 据 库<br />

18.1 PostgreSQL<br />

更 改 root 用 户 或 其 它 用 户 的 密 码<br />

# psql -d template1 -U pgsql<br />

> alter user pgsql with password 'pgsql_password'; # pgsql 为 需 要 更 改 密 码 的 用 户 名<br />

创 建 用 户 和 数 据 库<br />

命 令 createuser, dropuser, createdb 和 dropdb 等 同 于 SQL 命 令<br />

42<br />

的 快 捷 方 式 。 我 们 创 建 一 个 新 用 户 叫 bob<br />

和 一 个 数 据 库 叫 bobdb; 使 用 数 据 库 的 超 级 用 户 pgsql 来 创 建 :<br />

# createuser -U pgsql -P bob # -P 会 请 求 一 个 秘 密<br />

# createdb -U pgsql -O bob bobdb # 新 数 据 库 bobdn 的 所 有 者 是 bob 43<br />

# dropdb bobdb # 删 除 数 据 库 bobdb<br />

# dropuser bob # 删 除 用 户 bob<br />

一 般 数 据 库 认 证 机 制 配 置 在 pg_hba.conf 文 件 中 。<br />

允 许 远 程 访 问<br />

文 件 $PGSQL_DATA_D/postgresql.conf 可 指 定 绑 定 地 址 。 对 于 Postgres 8.x 通 常 为 listen_addresses =<br />

'*'。<br />

文 件 $PGSQL_DATA_D/pg_hba.conf 定 义 了 访 问 控 制 。 举 例 :<br />

# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD<br />

host bobdb bob 212.117.81.42 255.255.255.255 password<br />

host all all 0.0.0.0/0 password<br />

备 份 和 恢 复<br />

使 用 pgsql 或 postgres 用 户 来 完 成 备 份 与 恢 复 。 下 面 是 备 份 和 恢 复 单 个 数 据 库 :<br />

# pg_dump --clean dbname > dbname_sql.dump<br />

# psql dbname < dbname_sql.dump<br />

备 份 和 恢 复 所 有 数 据 库 ( 包 括 用 户 ):<br />

41. 译 注 : 此 例 事 实 上 利 用 管 道 (pipe) 方 式 将 PDF 的 转 换 结 果 利 用 -sOutputFile 选 项 导 入 给 lpr 打 印 。<br />

42. 译 注 : 其 实 是 一 个 Shell 脚 本<br />

43. 译 注 : 通 常 , 执 行 这 个 命 令 的 数 据 库 用 户 成 为 新 数 据 库 的 所 有 者 。 不 过 , 如 果 执 行 用 户 拥 有 合 适 的 权 限 , 那 么 他 可 以 通 过 -O 指 定 合 适 的 用 户 。<br />

44


# pg_dumpall --clean > full.dump<br />

# psql -f full.dump postgres<br />

在 这 个 例 子 中 , 你 可 以 声 明 任 意 现 有 的 数 据 库 进 行 连 接 , 但 是 如 果 你 是 向 一 个 空 的 数 据 库 集 群 装 载 , 那 么<br />

postgres 应 该 是 比 较 好 的 选 择 。<br />

18.2 MySQL<br />

更 改 mysql root 用 户 或 其 它 用 户 的 密 码<br />

方 法 1<br />

# /etc/init.d/mysql stop<br />

or<br />

# killall mysqld<br />

# mysqld --skip-grant-tables<br />

# mysqladmin -u root password 'newpasswd'<br />

# /etc/init.d/mysql start<br />

方 法 2<br />

# mysql -u root mysql<br />

mysql> UPDATE USER SET PASSWORD=PASSWORD("newpassword") where user='root';<br />

mysql> FLUSH PRIVILEGES;<br />

# 使 用 用 户 名 替 代 "root"<br />

mysql> quit<br />

创 建 用 户 和 数 据 库<br />

# mysql -u root mysql<br />

mysql> CREATE DATABASE bobdb;<br />

mysql> GRANT ALL ON *.* TO 'bob'@'%' IDENTIFIED BY 'pwd';<br />

# 使 用 localhost 替 代 % 来 限 制 网 络 访 问<br />

mysql> DROP DATABASE bobdb;<br />

# 删 除 数 据 库 bobdb<br />

mysql> DROP USER bob;<br />

# 删 除 用 户 bob<br />

mysql> DELETE FROM mysql.user WHERE user='bob and host='hostname';<br />

# 删 除 mysql 数 据 库 user 表 中 user=bob,host=hostname 的 记 录<br />

mysql> FLUSH PRIVILEGES;<br />

允 许 远 程 访 问<br />

远 程 访 问 通 常 允 许 单 个 数 据 库 , 而 不 是 所 有 的 数 据 库 。 文 件 /etc/my.cnf 包 含 约 定 的 IP 地 址 。 通 常 为<br />

bind-address = 绑 定 地 址 。<br />

# mysql -u root mysql<br />

mysql> GRANT ALL ON bobdb.* TO bob@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'PASSWORD';<br />

mysql> REVOKE GRANT OPTION ON foo.* FROM bar@'xxx.xxx.xxx.xxx';<br />

mysql> FLUSH PRIVILEGES;<br />

# 使 用 'hostname' 也 可 为 '%' 来 完 全 访 问<br />

备 份 和 恢 复<br />

备 份 和 恢 复 单 个 数 据 库 :<br />

# mysqldump -u root -psecret --add-drop-database dbname > dbname_sql.dump<br />

# mysql -u root -psecret -D dbname < dbname_sql.dump<br />

备 份 和 恢 复 所 有 的 数 据 库 :<br />

— 数 据 库 —<br />

# mysqldump -u root -psecret --add-drop-database --all-databases > full.dump<br />

# mysql -u root -psecret < full.dump<br />

这 里 mysql root 的 密 码 为 "secret",-p 选 项 后 面 没 有 空 格 。 当 单 独 使 用 -p 选 项 ( 不 跟 密 码 ), 命 令 行 提 示 符<br />

后 会 要 求 输 入 密 码 。<br />

45


— 磁 盘 限 额 —<br />

18.3 SQLite<br />

SQLite 44<br />

是 一 个 小 而 强 大 的 、 独 立 的 (self-contained)、 无 服 务 器 的 (serverless)、 零 配 置 的<br />

(zero-configuration) SQL 数 据 库 。<br />

备 份 和 恢 复<br />

实 用 备 份 和 恢 复 SQLite 数 据 库 命 令 。 举 个 例 子 , 你 可 以 编 辑 备 份 文 件 来 修 改 字 段 的 属 性 和 类 型 , 然 后 再 恢 复 这<br />

个 数 据 库 。 这 比 使 用 SQL 命 令 来 得 容 易 。 对 于 3.x 数 据 库 可 使 用 sqlite3。<br />

# sqlite database.db .dump > dump.sql # 备 份<br />

# sqlite database.db < dump.sql # 恢 复<br />

转 换 2.x 到 3.x 数 据 库<br />

sqlite database_v2.db .dump | sqlite3 database_v3.db<br />

19 磁 盘 限 额<br />

磁 盘 限 额 用 来 限 制 磁 盘 空 间 大 小 和 / 或 用 户 ( 或 用 户 组 ) 可 用 的 文 件 数 。The quotas are allocated on a<br />

per-file system basis and are enforced by the kernel.<br />

19.1 Linux 设 置<br />

Quota 工 具 包 通 常 已 安 装 , 其 包 含 一 些 命 令 行 工 具 。<br />

在 fstab 中 激 活 用 户 配 额 并 重 新 挂 载 分 区 。 如 果 分 区 正 在 使 用 , 关 闭 所 有 使 用 的 文 件 , 或 者 重 启 系 统 。 添 加<br />

usrquota 到 fstab 的 挂 载 类 型 中 , 举 个 例 子 :<br />

/dev/sda2 /home reiserfs rw,acl,user_xattr,usrquota 1 1<br />

# mount -o remount /home<br />

# mount # 检 查 usrquota 已 经 激 活 , 否 则 重 启<br />

用 quotacheck 初 始 化 quota.user 文 件 。<br />

# quotacheck -vum /home<br />

# chmod 644 /home/aquota.user # 让 用 户 检 查 自 己 的 配 额<br />

用 脚 本 (e.g. SuSE 的 /etc/init.d/quotad) 或 quotaon 来 启 用 限 额 :<br />

quotaon -vu /home<br />

检 查 配 额 启 用 情 况 :<br />

quota -v<br />

19.2 FreeBSD 设 置<br />

Quota 工 具 是 FreeBSD 基 本 系 统 的 一 部 分 , 然 而 内 核 需 要 quota 选 项 。 如 果 不 存 在 , 新 增 它 并 重 新 编 译 内 核 。<br />

options QUOTA<br />

与 Linux 一 样 , 添 加 限 额 到 fstab 选 项 ( 是 userquota, 而 不 是 usrquota) 中 :<br />

/dev/ad0s1d /home ufs rw,noatime,userquota 2 2<br />

# mount /home # 重 新 挂 载 分 区<br />

在 /etc/rc.conf 中 启 用 磁 盘 限 额 并 开 启 quota 服 务 。<br />

# grep quotas /etc/rc.conf<br />

enable_quotas="YES"<br />

check_quotas="YES"<br />

# /etc/rc.d/quota start<br />

# 在 启 动 时 打 开 限 额 ( 或 者 "NO")<br />

# 在 启 动 时 检 查 限 额 ( 或 者 "NO")<br />

44.http://www.sqlite.org<br />

46


— Shells —<br />

19.3 分 配 限 额<br />

磁 盘 限 额 默 认 并 不 限 制 ( 设 置 为 0)。 用 edquota 来 对 单 用 户 进 行 限 制 。 一 个 quota 也 可 给 许 多 用 户 复 用 。 虽 然<br />

quota 实 现 之 间 的 文 件 结 构 不 同 , 但 其 原 理 是 相 同 的 : 限 制 节 点 (inodes) 数 量 以 及 使 用 者 可 以 取 用 的 磁 盘 区 块 数<br />

量 。Only change the values of soft and hard. 如 果 未 指 定 , 默 认 区 块 大 小 为 1k。 使 用 edquota -t 设 置<br />

grace 时 间 。 举 个 例 子 :<br />

# edquota -u colin<br />

Linux<br />

Disk quotas for user colin (uid 1007):<br />

Filesystem blocks soft hard inodes soft hard<br />

/dev/sda8 108 1000 2000 1 0 0<br />

FreeBSD<br />

Quotas for user colin:<br />

/home: kbytes in use: 504184, limits (soft = 700000, hard = 800000)<br />

inodes in use: 1792, limits (soft = 0, hard = 0)<br />

给 许 多 用 户 分 配 限 额<br />

命 令 edquota -p 用 来 复 用 一 个 quota 给 其 他 用 户 。 举 个 例 子 , 复 用 所 指 用 户 的 限 额 给 所 有 用 户 :<br />

# edquota -p refuser `awk -F: $3 > 499 {print $1}' /etc/passwd`<br />

# edquota -p refuser user1 user2 # 复 用 给 2 个 用 户<br />

检 查<br />

用 户 只 需 输 入 quota ( 文 件 quota.user 必 须 可 读 ) 来 可 以 检 查 他 们 的 限 额 。Root 可 以 查 看 所 有 用 户 的 限 额 。<br />

# quota -u colin # 查 看 用 户 的 限 额<br />

# repquota /home # 所 有 用 户 在 这 个 分 区 上 的 限 额 情 况<br />

20 SHELLS<br />

许 多 Linux 发 行 版 使 用 BASH Shell,BSD 使 用 的 是 tcsh,Bourne Shell 仅 用 于 脚 本 。 过 滤 器 (Filter) 非 常 有<br />

用 并 且 可 用 于 管 道 (pipe):<br />

grep 模 式 匹 配<br />

sed 查 找 并 替 换 字 符 串 或 字 符<br />

cut 从 一 个 标 记 开 始 打 印 所 指 定 列 数 据<br />

sort 按 字 母 或 数 字 排 序<br />

uniq 删 除 一 个 文 件 中 重 复 行<br />

举 个 例 子 , 一 次 使 用 所 有 命 令 :<br />

# ifconfig | sed 's/ / /g' | cut -d" " -f1 | uniq | grep -E "[a-z0-9]+" | sort -r<br />

# ifconfig | sed '/.*inet addr:/!d;s///;s/ .*//'|sort -t. -k1,1n -k2,2n -k3,3n -k4,4n<br />

sed 的 模 式 字 符 串 中 的 第 一 个 字 符 是 一 个 tab。 要 在 命 令 控 制 台 中 输 入 tab, 可 以 使 用 ctrl-v ctrl-tab。<br />

20.1 bash<br />

Bash、sh 的 重 定 向<br />

45<br />

和 管 道 :<br />

# cmd 1> file # 重 定 向 标 准 输 出 到 file。<br />

# cmd 2> file # 重 定 向 标 准 错 误 输 出 到 file。<br />

# cmd 1>> file # 重 定 向 标 准 输 出 并 追 加 到 file。<br />

45. 译 注 : 当 执 行 一 个 程 序 时 , 运 行 该 程 序 的 进 程 打 开 了 3 个 文 件 描 述 符 , 分 别 是 :0( 标 准 输 入 )、1( 标 准 输 出 ) 和 2( 标 准 错 误 输 出 )。 重 定 向 输<br />

出 符 号 (>) 是 1> 的 简 写 , 它 通 知 shell 重 定 向 标 准 输 出 。 类 似 的 ,< 是 0< 的 简 写 , 表 示 重 定 向 标 准 输 入 。 符 号 2> 将 重 定 向 标 准 错 误 输<br />

出 。<br />

47


— Shells —<br />

# cmd &> file # 重 定 向 标 准 输 出 和 标 准 错 误 输 出 到 file。<br />

# cmd >file 2>&1 # 重 定 向 标 准 错 误 输 出 到 标 准 输 出 然 后 重 定 向 到 file。<br />

# cmd1 | cmd2 # cmd1 的 输 出 通 过 管 道 连 接 到 cmd2 的 输 入<br />

# cmd1 2>&1 | cmd2 # cmd1 的 输 出 和 错 误 输 出 通 过 管 道 连 接 到 cmd2 的 输 入<br />

修 改 你 的 配 置 文 件 ~/.bashrc ( 也 可 以 是 ~/.bash_profile)。 下 列 条 目 非 常 有 用 , 使 用 ". .bashrc" 重 新 加 载 。<br />

# in .bashrc<br />

bind '"\e[A"':history-search-backward # 使 用 上 下 键 查 找<br />

bind '"\e[B"':history-search-forward # 历 史 命 令 。 无 价 之 宝 !<br />

set -o emacs # Set emacs mode in bash ( 看 下 面 )<br />

set bell-style visible<br />

# Do not beep, inverse colors<br />

# 设 置 一 个 漂 亮 的 提 示 符 像 [user@host]/path/todir><br />

PS1="\[\033[1;30m\][\[\033[1;34m\]\u\[\033[1;30m\]"<br />

PS1="$PS1@\[\033[0;33m\]\h\[\033[1;30m\]]\[\033[0;37m\]"<br />

PS1="$PS1\w\[\033[1;30m\]>\[\033[0m\]"<br />

# 要 检 查 当 前 可 用 别 名 (alias), 只 需 简 单 输 入 命 令 alias<br />

alias ls='ls -aF' # 添 加 指 示 符 (*/=>@| 其 中 之 一 )<br />

alias ll='ls -aFls'<br />

# 清 单<br />

alias la='ls -all'<br />

alias ..='cd ..'<br />

alias ...='cd ../..'<br />

export HISTFILESIZE=5000<br />

# 巨 大 的 历 史 记 录<br />

export CLICOLOR=1 # 使 用 颜 色 ( 如 果 可 用 )<br />

export LSCOLORS=ExGxFxdxCxDxDxBxBxExEx<br />

20.2 tcsh<br />

Tcsh、csh 的 重 定 向 和 管 道 (> 和 >> 同 sh 中 一 样 ):<br />

# cmd >& file # 重 定 向 标 准 输 出 和 标 准 错 误 输 出 到 file。<br />

# cmd >>& file # 追 加 标 准 输 出 和 标 准 错 误 输 出 到 file。<br />

# cmd1 | cmd2 # cmd1 的 输 出 通 过 管 道 连 接 到 cmd2 的 输 入<br />

# cmd1 |& cmd2 # cmd1 的 输 出 和 错 误 输 出 通 过 管 道 连 接 到 cmd2 的 输 入<br />

Csh/tcsh 的 设 置 在 ~/.cshrc 中 , 使 用 "source .cshrc" 来 重 新 加 载 。 例 子 :<br />

# in .cshrc<br />

alias ls 'ls -aF'<br />

alias ll 'ls -aFls'<br />

alias la 'ls -all'<br />

alias .. 'cd ..'<br />

alias ... 'cd ../..'<br />

set prompt = "%B%n%b@%B%m%b%/> " # 像 user@host/path/todir><br />

set history = 5000<br />

set savehist = ( 6000 merge )<br />

set autolist # 控 制 命 令 补 全 和 变 量 补 全<br />

set visiblebell # 使 用 闪 动 屏 幕 的 方 式 来 取 代 蜂 鸣 器 鸣 叫<br />

# Bindkey 和 颜 色<br />

bindkey -e Select Emacs bindings # 将 命 令 行 编 辑 器 切 换 到 emacs 模 式<br />

bindkey -k up history-search-backward # 使 用 上 下 键 来 搜 索<br />

bindkey -k down history-search-forward<br />

setenv CLICOLOR 1 # 使 用 颜 色 ( 可 能 的 话 )<br />

setenv LSCOLORS ExGxFxdxCxDxDxBxBxExEx<br />

该 emacs 模 式 将 使 用 emacs 快 捷 键 来 修 改 命 令 提 示 行 。 这 是 非 常 有 用 的 ( 不 单 为 Emacs 用 户 )。 最 常 用 的 命 令<br />

如 下 :<br />

C-a 移 动 光 标 到 行 头<br />

C-e 移 动 光 标 到 行 尾<br />

M-b 移 动 光 标 到 前 一 个 单 词<br />

M-f 移 动 光 标 到 后 一 个 单 词<br />

M-d 剪 切 下 一 个 单 词<br />

C-w 剪 切 最 后 一 个 单 词<br />

C-u 剪 切 光 标 前 所 有 字 符<br />

48


— 脚 本 —<br />

C-k 剪 切 光 标 后 所 有 字 符<br />

C-y 粘 帖 最 后 剪 切 的 字 符 ( 简 易 的 粘 帖 )<br />

C-_ 重 做<br />

注 意 : C- = 按 住 control 键 ,M- = 按 住 meta ( 它 通 常 为 alt 或 者 escape) 键 。<br />

21 脚 本<br />

基 础 (p49) | 脚 本 实 例 (p50) | sed/ 实 用 命 令 (p50)<br />

Bourne shell 46<br />

个 好 的 参 考 。<br />

(/bin/sh) 存 在 于 所 有 的 <strong>Unix</strong> 系 统 上 , 并 且 用 她 写 的 脚 本 是 ( 完 全 ) 可 移 植 的 ; man 1 sh 是 一<br />

21.1 基 础<br />

变 量 和 参 数<br />

使 用 variable=value 的 命 令 格 式 设 置 变 量 , 其 中 variable 是 变 量 名 称 ,value 是 打 算 赋 给 该 变 量 的 值 。 使 用<br />

$variable 获 取 变 量 值 。<br />

MESSAGE="Hello World"<br />

# 赋 予 一 个 字 符 串<br />

PI=3.1415<br />

# 赋 予 一 个 十 进 制 小 数<br />

N=8<br />

TWON=`expr $N * 2` # 算 术 表 达 式 ( 只 限 整 数 )<br />

TWON=$(($N * 2))<br />

# 另 一 种 语 法<br />

TWOPI=`echo "$PI * 2" | bc -l`<br />

# 使 用 bc 进 行 浮 点 运 算<br />

ZERO=`echo "c($PI/4)-sqrt(2)/2" | bc -l`<br />

命 令 行 参 数 :<br />

$0, $1, $2, ... # $0 命 令 本 身<br />

$# # 命 令 参 数 个 数<br />

$* # 所 有 参 数 ( 也 可 以 是 $@)<br />

一 些 特 殊 的 变 量<br />

$$ # 当 前 进 程 ID<br />

$? # 最 后 命 令 退 出 状 态 码<br />

command<br />

if [ $? != 0 ]; then<br />

echo "command failed"<br />

fi<br />

mypath=`pwd`<br />

mypath=${mypath}/file.txt<br />

echo ${mypath##*/}<br />

# 只 显 示 文 件 名<br />

echo ${mypath%%.*}<br />

var2=${var:=string}<br />

结 构 控 制<br />

for file in `ls`<br />

do<br />

echo $file<br />

done<br />

count=0<br />

while [ $count -lt 5 ]; do<br />

echo $count<br />

sleep 1<br />

count=$(($count + 1))<br />

# 除 了 扩 展 名 的 全 路 径<br />

# 如 果 var 没 有 被 赋 值 , 则 string 值 先 赋 值 给 var,<br />

# 然 后 再 赋 值 给 var2<br />

46. 译 注 :Shell 存 在 很 多 种 , 如 bash(Bourne Again Shell),csh(C Shell),tcsh(TC Shell),zsh(Z Shell) 等 。 通 过 ps 命 令 可 识 别 出 正<br />

在 运 行 的 是 哪 种 Shell。<br />

49


— 脚 本 —<br />

done<br />

myfunction() {<br />

find . -type f -name "*.$1" -print<br />

}<br />

myfunction "txt"<br />

# $1 为 方 法 的 第 一 个 参 数<br />

产 生 一 个 文 件<br />

MYHOME=/home/colin<br />

cat > testhome.sh &2 "Usage: $0 HtmlFile"<br />

exit 1<br />

# 如 果 不 等 于 1, 非 0 退 出<br />

fi<br />

file=$1<br />

fname=${file%.*}<br />

fext=${file#*.}<br />

# 文 件 变 量<br />

# 文 件 名 变 量<br />

# 文 件 扩 展 名 变 量<br />

prince $file -o $fname.pdf<br />

# www.princexml.com<br />

pdftops -paper A4 -noshrink $fname.pdf $fname.ps # 创 建 postscript 小 册 子<br />

cat $fname.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps<br />

ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $fname.book.ps $fname.book.pdf<br />

# 在 Windows 上 使 用 #a4 和 #None!<br />

exit 0<br />

# exit 0 意 为 成 功<br />

21.3 一 些 sed 命 令<br />

这 里 是 单 行 sed 命 令 的 金 矿<br />

47<br />

。 还 有 一 个 很 好 的 sed 介 绍 及 教 程<br />

48<br />

。<br />

sed 's/string1/string2/g'<br />

sed -i 's/wroong/wrong/g' *.txt<br />

sed 's/\(.*\)1/\12/g'<br />

sed '//,//d' t.xhtml<br />

sed '/ *#/d; /^ *$/d'<br />

sed 's/[ \t]*$//'<br />

sed 's/^[ \t]*//;s/[ \t]*$//'<br />

sed 's/[^*]/[&]/'<br />

sed = file | sed 'N;s/\n/\t/' > file.num<br />

21.4 正 则 表 达 式<br />

# 替 换 string1 为 string2<br />

# 用 g 替 换 所 有 返 回 的 单 词<br />

# 修 改 anystring1 为 anystring2<br />

# 删 除 以 开 始 , 以 结 尾 的 行<br />

# 删 除 注 释 和 空 行<br />

# 删 除 行 尾 空 格 ( 使 用 tab 代 替 \t)<br />

# 删 除 行 头 尾 空 格<br />

# 括 住 首 字 符 [] top -> [t]op<br />

# 为 文 件 添 加 行 号<br />

一 些 基 本 的 正 则 表 达 式 同 样 可 用 于 sed。 作 为 一 个 良 好 的 启 蒙 , 可 看 基 本 正 则 语 法<br />

49<br />

。<br />

47.http://student.northpark.edu/pemente/sed/sed1line.txt<br />

48.http://www.grymoire.com/<strong>Unix</strong>/Sed.html<br />

50


— 编 程 —<br />

[\^$.|?*+()<br />

# 特 殊 字 符 , 其 他 字 符 将 匹 配 自 身<br />

\ # 转 义 特 殊 字 符 , 当 成 普 通 字 符 对 待<br />

* # 重 复 前 项 0 次 或 多 次<br />

. # 单 个 字 符 除 换 行 符<br />

.* # 匹 配 0 个 或 多 个 字 符<br />

^<br />

# 匹 配 字 符 串 行 开 始 处<br />

$ # 匹 配 字 符 串 行 结 尾 处<br />

.$ # 匹 配 字 符 串 行 最 后 一 个 字 符<br />

^ $<br />

# 匹 配 单 个 空 格 的 行<br />

[^A-Z]<br />

# 匹 配 任 何 以 A-Z 字 符 开 始 的 行<br />

21.5 一 些 实 用 命 令<br />

下 列 命 令 对 于 包 含 于 一 个 脚 本 或 者 单 行 命 令 来 说 很 有 用 。<br />

sort -t. -k1,1n -k2,2n -k3,3n -k4,4n # 排 序 IPv4 格 式 的 IP 地 址<br />

echo 'Test' | tr '[:lower:]' '[:upper:]' # 转 换 成 大 写<br />

echo foo.bar | cut -d . -f 1<br />

# 返 回 foo<br />

PID=$(ps | grep script.sh | grep bin | awk '{print $1}') # 正 在 运 行 名 为 script 脚 本 的 PID<br />

PID=$(ps axww | grep [p]ing | awk '{print $1}')<br />

# ping 的 PID (w/o grep pid)<br />

IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//') # Linux<br />

IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//') # FreeBSD<br />

if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi # 文 件 改 变 了 ?<br />

cat /etc/master.passwd | grep -v root | grep -v \*: | awk -F":" \ # 创 建 http passwd<br />

'{ printf("%s:%s\n", $1, $2) }' > /usr/local/etc/apache2/passwd<br />

testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \ # 查 看 passwd 中 的 用 户<br />

root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$)<br />

:(){ :|:& };:<br />

50<br />

# bash fork 炸 弹 。 会 干 掉 你 的 机 器<br />

tail +2 file > file2<br />

# 删 除 文 件 的 第 一 行<br />

我 使 用 一 种 小 伎 俩 来 一 次 更 改 许 多 文 件 的 扩 展 名 。 举 个 例 子 , 从 .cxx 到 .cpp。 排 除 最 后 的 | sh 先 测 试 一<br />

下 。 你 同 样 可 以 使 用 命 令 rename 来 做 这 些 , 如 果 安 装 了 的 话 。 或 者 使 用 bash 内 建 命 令 。<br />

# ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh<br />

# ls *.c | sed "s/.*/cp & &.$(date "+%Y%m%d")/" | sh # 如 拷 贝 *.c 成 *.c.20080401<br />

# rename .cxx .cpp *.cxx # 重 命 名 所 有 .cxx 成 .cpp<br />

# for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done # bash 内 建 的<br />

22 编 程<br />

22.1 C 基 础<br />

strcpy(newstr,str) /* 拷 贝 str 到 newstr */<br />

expr1 ? expr2 : expr3 /* if (expr1) expr2 else expr3 */<br />

x = (y > z) ? y : z; /* if (y > z) x = y; else x = z; */<br />

int a[]={0,1,2}; /* 初 始 化 数 组 ( 或 者 a[3]={0,1,2}; */<br />

int a[2][3]={{1,2,3},{4,5,6}}; /* 初 始 化 二 维 数 组 */<br />

int i = 12345; /* 从 i 转 换 成 char str */<br />

char str[10];<br />

sprintf(str, "%d", i);<br />

22.2 C 实 例<br />

一 个 最 小 化 的 C 程 式 simple.c:<br />

#include <br />

main() {<br />

int number=42;<br />

49.http://www.regular-expressions.info/reference.html<br />

50. 译 注 :http://forum.ubuntu.org.cn/viewtopic.php?t=92074<br />

51


— 编 程 —<br />

}<br />

编 译 :<br />

printf("The answer is %i\n", number);<br />

# gcc simple.c -o simple<br />

# ./simple<br />

The answer is 42<br />

22.3 C++ 基 础<br />

*pointer<br />

&obj<br />

obj.x<br />

pobj->x<br />

// 指 向 对 象 的 指 针<br />

// 对 象 obj 的 地 址<br />

// 类 ( 对 象 ) obj 成 员 x<br />

// 指 针 pobj 指 向 类 ( 对 象 ) 成 员 x<br />

// (*pobj).x 同 pobj->x<br />

22.4 C++ 实 例<br />

来 一 个 稍 微 现 实 一 点 的 C++ 程 序 , 我 们 在 一 个 头 文 件 (IPv4.h) 中 创 建 一 个 类 并 且 实 现 它 (IPv4.cpp), 然 后 创 建<br />

一 个 程 式 来 使 用 其 功 能 。 这 个 类 的 成 员 方 法 实 现 了 IP 地 址 从 一 串 整 数 转 换 成 我 们 熟 知 的 点 分 格 式 。 这 是 一 个 最<br />

小 化 的 C++ 程 式 和 多 源 文 件 (multi-source) 的 编 译 。<br />

IPv4 class<br />

IPv4.h:<br />

#ifndef IPV4_H<br />

#define IPV4_H<br />

#include <br />

namespace GenericUtils {<br />

// 创 建 namespace<br />

class IPv4 {<br />

// 类 定 义<br />

public:<br />

IPv4();<br />

~IPv4();<br />

std::string IPint_to_IPquad(unsigned long ip);// 成 员 方 法 接 口<br />

};<br />

} //namespace GenericUtils<br />

#endif // IPV4_H<br />

IPv4.cpp:<br />

#include "IPv4.h"<br />

#include <br />

#include <br />

using namespace std;<br />

using namespace GenericUtils;<br />

IPv4::IPv4() {}<br />

IPv4::~IPv4() {}<br />

string IPv4::IPint_to_IPquad(unsigned long ip) {<br />

ostringstream ipstr;<br />

ipstr > 24)<br />

16)<br />

8)<br />


— 在 线 帮 助 —<br />

程 序 simplecpp.cpp<br />

#include "IPv4.h"<br />

#include <br />

#include <br />

using namespace std;<br />

int main (int argc, char* argv[]) {<br />

string ipstr;<br />

unsigned long ipint = 1347861486;<br />

GenericUtils::IPv4 iputils;<br />

ipstr = iputils.IPint_to_IPquad(ipint);<br />

cout


— 在 线 帮 助 —<br />

Linux 命 令 行 列 表<br />

Short Linux reference<br />

www.linuxguide.it/commands_list.php<br />

www.pixelbeat.org/cmdline.html<br />

That's all folks!<br />

This document: "<strong>Unix</strong> <strong>Toolbox</strong> revision 12" is licensed under a Creative Commons Licence<br />

[Attribution - Share Alike]. © Colin Barschel and Greco Shi 2007-2008. Some rights reserved.<br />

54

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!