Unix Toolbox - 中文版
Table of Contents
- 1. 介绍
- 2. 系统
- 3. 进程
- 4. 文件系统
- 5. 网络
- 6. SSH SCP
- 7. 使用 SSH 建立 VPN
- 8. RSYNC
- 9. SUDO
- 10. 文件加密
- 11. 分区加密
- 12. SSL 认证
- 13. CVS
- 14. SVN
- 15. 实用命令
- 16. 软件安装
- 17. 媒体转换
- 18. 打印
- 19. 数据库
- 20. 磁盘限额
- 21. SHELLS
- 22. 脚本
- 23. 编程
- 24. 在线帮助
1. 介绍
这是一份收集Unix/Linux/BSD命令和任务的文档, 它有助于高级用户或IT工作. 它是一份简明扼要的实用指南, 当然读者应该知道他/她在干什么.
Unix Toolbox 版本: 12 你可以到 本文档的最新版 找到. PDF版本可以替换链接中的.xhtml为 .pdf , 小册子版本可以替换成 .book.pdf . 用双面打印机可将小册子打印成册. 这份XHTML页面可以通过CSS3相兼容的应用程序转换成一份漂亮的PDF文档(看 脚本例子).
错误报告和评论是最欢迎的 - c@cb.vu Colin Barschel. 你可以到中文最新版找到. 也可到我的主页获取http://silenceisdefeat.org/~greco/unixtoolbox_zh_CN.xhtml 关于中文版的任何错误和修正请发送E-Mail到 ]>
© Colin Barschel and Greco Shi 2007-2008. Some rights reserved under Creative Commons.
2. 系统
2.1. 正在运行的内核和系统信息
# uname -a # 获取内核版本(和BSD版本) # lsb_release -a # 显示任何 LSB 发行版版本信息 # cat /etc/SuSE-release # 获取 SuSE 版本 # cat /etc/debian_version # 获取 Debian 版本 # uptime # 显示系统开机运行到现在经过的时间 # hostname # 显示系统主机名 # hostname -i # 显示主机的 IP 地址 # man hier # 描述文件系统目录结构 # last reboot # 显示系统最后重启的历史记录
2.2. 硬件信息
2.2.1. 内核检测到的硬件信息
# dmesg # 检测到的硬件和启动的消息 # lsdev # 关于已安装硬件的信息 # dd if=/dev/mem bs=1k skip=768 count=256 2>/dev/null | strings -n 8 # 读取 BIOS 信息
2.2.2. Linux
# cat /proc/cpuinfo # CPU 讯息 # cat /proc/meminfo # 内存信息 # grep MemTotal /proc/meminfo # 显示物理内存大小 # watch -n1 'cat /proc/interrupts' # 监控内核处理的所有中断 # free -m # 显示已用和空闲的内存信息 (-m 为 MB) # cat /proc/devices # 显示当前核心配置的设备 # lspci -tv # 显示 PCI 设备 # lsusb -tv # 显示 USB 设备 # lshal # 显示所有设备属性列表 # dmidecode # 显示从 BIOS 中获取的硬件信息
2.2.3. FreeBSD
# sysctl hw.model # CPU 讯息 # sysctl hw # 得到很多硬件信息 # sysctl vm # 虚拟内存使用情况 # dmesg | grep "real mem" # 物理内存 # sysctl -a | grep mem # 内核内存的设置和信息 # sysctl dev # 显示当前核心配置的设备 # pciconf -l -cv # 显示 PCI 设备 # usbdevs -v # 显示 USB 设备 # atacontrol list # 显示 ATA 设备
2.3. 显示状态信息
以下的命令有助于找出正在系统中运行着的程序.
# top # 显示和更新使用 cpu 最多的进程 # mpstat 1 # 显示进程相关的信息 # vmstat 2 # 显示虚拟内存的状态信息 # iostat 2 # 显示 I/O 状态信息(2 秒 间隙) # systat -vmstat 1 # 显示 BSD 系统状态信息(1 秒 间隙) # systat -tcp 1 # 显示 BSD TCP 连接信息(也可以试试 -ip) # systat -netstat 1 # 显示 BSD 当前网络连接信息 # systat -ifstat 1 # 显示 BSD 当前网卡带宽信息 # systat -iostat 1 # 显示 BSD CPU 和磁盘使用情况 # tail -n 500 /var/log/messages # 显示最新500条内核/系统日志的信息 # tail /var/log/warn # 显示系统警告信息(看syslog.conf)
2.4. 用户
# id # 显示当前用户和用户组的 ID # last # 列出目前与过去登入系统的用户相关信息 # who # 显示目前登入系统的用户信息 # groupadd admin # 建立新组"admin"和添加新用户 colin 并加入 admin 用户组(Linux/Solaris) # useradd -c "Colin Barschel" -g admin -m colin # userdel colin # 删除用户 colin(Linux/Solaris) # adduser joe # FreeBSD 添加用户 joe(交互式) # rmuser joe # FreeBSD 删除用户 joe(交互式) # pw groupadd admin # 在 FreeBSD 上使用 pw # pw groupmod admin -m newmember # 添加新用户到一个组 # pw useradd colin -c "Colin Barschel" -g admin -m -s /bin/tcsh # pw userdel colin; pw groupdel admin
加密过的密码存储在 /etc/shadow (Linux and Solaris) 或 /etc/master.passwd (FreeBSD) 中. 如果手动修改了 master.passwd, 需要运行 # pwd_mkdb -p master.passwd 来重建数据库.
使用 nologin 来临时阻止所有用户登录(root除外). 用户登录时将会显示 nologin 中的信息.
# echo "Sorry no login now" > /etc/nologin # (Linux) # echo "Sorry no login now" > /var/run/nologin # (FreeBSD)
2.5. 限制
某些应用程序需要设置可打开最大文件和 socket 数量(像代理服务器, 数据库). 默认限制通常很低.
2.5.1. Linux
- 每 shell/脚本
shell 的限制是受 ulimit 支配的. 使用 ulimit -a 可查看其状态信息. 举个例子, 改变可打开最大文件数从 1024 到 10240, 可以这么做:
# ulimit -n 10240 # 这只在shell中有用
ulimit 命令可以使用在脚本中来更改对此脚本的限制.
- 每 用户/进程
登录用户和应用程序的限制可以在
/etc/security/limits.conf中配置. 举个例子:# cat /etc/security/limits.conf * hard nproc 250 # 限制所有用户进程数 asterisk hard nofile 409600 # 限制应用程序可打开最大文件数
- 系统级
用sysctl来设置内核限制. 要使其永久, 可以在
/etc/sysctl.conf中进行配置.# sysctl -a # 显示所有系统限制 # sysctl fs.file-max # 显示系统最大文件打开数 # sysctl fs.file-max=102400 # 更改系统最大文件打开数 # cat /etc/sysctl.conf fs.file-max=102400 # 在 sysctl.conf 中的永久项 # cat /proc/sys/fs/file-nr # 在使用的文件句柄数
2.5.2. FreeBSD
- 每 shell/脚本
在 csh 或 tcsh 中使用 limits 命令, 在 sh 或 bash 中使用 ulimit 命令.
- 每 用户/进程
在
/etc/login.conf中配置登录后的默认限制. 未作限制的值为系统最大限制值. - 系统级
内核限制同样使用 sysctl 来设置. 永久配置, 在
/etc/sysctl.conf或/boot/loader.conf中. 其语法与 Linux 相同, 只是键值不同.# sysctl -a # 显示所有系统限制 # sysctl kern.maxfiles=XXXX # 最大文件描述符数
/etc/sysctl.conf 中的永久项:
kern.ipc.nmbclusters=32768 kern.maxfiles=65536 # Squid 通常用这个值 kern.maxfilesperproc=32768 kern.ipc.somaxconn=8192 # TCP 列队. apache/sendmail 最好用这个值
# sysctl kern.openfiles # 在使用的文件描述符数 # sysctl kern.ipc.numopensockets # 已经开启的 socket 数目
详情请看 FreeBSD 手册 11章.
2.5.3. Solaris
在 /etc/system 中的下列设置, 会提高每个进程可以打开最大文件描述符的数量:
set rlim_fd_max = 4096 # 一个进程可以打开文件描述符的"硬"限制 set rlim_fd_cur = 1024 # 一个进程可以打开文件描述符的"软"限制
2.6. 运行级别
2.6.1. Linux
一旦内核加载完成, 内核会启动 init 进程, 然后运行 rc 脚本, 之后运行所有属于其运行级别的命令脚本. 这些脚本都储存在 /etc/rc.d/rcN.d 中(N代表运行级别), 并且都建立着到 /etc/init.d 子目录中命令脚本程序的符号链接.
默认运行级别配置在 /etc/inittab 中. 它通常为 3 或 5:
# grep default: /etc/inittab id:3:initdefault:
可以使用 init 来改变当前运行级别. 举个例子:
# init 5 # 进入运行级别 5
运行级别列表如下:
- 0
- 系统停止
- 1
- 进入单用户模式(也可以是 S)
- 2
- 没有 NFS 特性的多用户模式
- 3
- 完全多用户模式(正常操作模式)
- 4
- 未使用
- 5
- 类似于级别3, 但提供 XWindow 系统登录环境
- 6
- 重新启动系统
使用 chkconfig 工具控制程序在一个运行级别启动和停止.
# chkconfig --list # 列出所有 init 脚本 # chkconfig --list sshd # 查看 sshd 在各个运行级别中的启动配置 # chkconfig sshd --level 35 on # 对 sshd 在级别 3 和 5 下创建启动项 # chkconfig sshd off # 在所有的运行级别下禁用 sshd
Debian 和基于Debian 发行版像 Ubuntu 或 Knoppix 使用命令 update-rc.d 来管理运行级别脚本. 默认启动为 2,3,4 和 5, 停止为 0,1 和 6.
# update-rc.d sshd defaults # 设置 sshd 为默认启动级别 # update-rc.d sshd start 20 2 3 4 5 . stop 20 0 1 6 . # 用显示参数 # update-rc.d -f sshd remove # 在所有的运行级别下禁用 sshd # shutdown -h now (或者 # poweroff) # 关闭停止系统
2.6.2. FreeBSD
BSD 启动步骤不同于 SysV, 她没有运行级别. 她的启动状态(单用户, 有或没有 XWindow)被配置在 /etc/ttys 中. 所有的系统脚本都位于 /etc/rc.d/=中, 第三方应用程序位于 =/usr/local/etc/rc.d/=中. service 的启动顺序被配置在 =/etc/rc.conf 和=/etc/rc.conf.local=中. 默认行为可在 /etc/defaults/rc.conf 中进行配置. 这些脚本至少响应 start|stop|status.
# /etc/rc.d/sshd status sshd is running as pid 552. # shutdown now # 进入单用户模式 # exit # 返回到多用户模式 # shutdown -p now # 关闭停止系统 # shutdown -r now # 重新启动系统
同样可以使用进程 init 进入下列状态级别. 举个例子: # init 6 为重启.
- 0
- 停止系统并关闭电源 (信号 USR2)
- 1
- 进入单用户模式 (信号 TERM)
- 6
- 重新启动 (信号 INT)
- c
- 阻止进一步登录 (信号 TSTP)
- q
- 重新检查 ttys(5) 文件 (信号 HUP)
2.7. 重设 root 密码
2.7.1. Linux 方法 1
在引导加载器(lilo 或 grub)中, 键入如下启选项:
init=/bin/sh
内核会挂载 root 分区, 进程 init 会启动 bourne shell 而不是 rc, 然后是运行级别. 使用命令 passwd 设置密码然后重启. 别忘了需要在单用户模式下做这些动作. 如果重启后 root 分区被挂载为只读, 重新挂在它为读写:
# mount -o remount,rw / # passwd # 或者删除 root 密码 (/etc/shadow) # sync; mount -o remount,ro / # sync 在重新挂在为只读之前 sync 一下 # reboot
2.7.2. FreeBSD 和 Linux 方法 2
FreeBSD 不会让你这么做. 解决方案是用其他操作系统(像系统紧急修复光盘)挂载 root 分区, 然后更改密码. 用 live cd 或安装盘启动进入修复模式后, 会得到一个 shell. 用 fdisk 查找 root 分区. 比如: fdisk /dev/sda 挂载它并使用 chroot 命令:
# mount -o rw /dev/ad4s3a /mnt # chroot /mnt # 改变程序执行时所参考的根目录位置为 /mnt # passwd # reboot
2.8. 内核模块
2.8.1. Linux
# lsmod # 列出所有已载入内核的模块 # modprobe isdn # 载入 isdn 模块
2.8.2. FreeBSD
# kldstat # 列出所有已载入内核的模块 # kldload crypto # 载入 crypto 模块
2.9. 编译内核
2.9.1. Linux
# cd /usr/src/linux # make mrproper # 清除所有东西, 包括配置文件 # make oldconfig # 从当前内核配置文件的基础上创建一个新的配置文件 # make menuconfig # 或者 xconfig (Qt) 或者 gconfig (GTK) # make # 创建一个已压缩的内核映像文件 # make modules # 编译模块 # make modules_install # 安装模块 # make install # 安装内核 # reboot
2.9.2. FreeBSD
要改变和重建内核, 需要拷贝源配置文件然后编辑它. 当然也可以直接编辑 GENERIC 文件.
# cd /usr/src/sys/i386/conf/ # cp GENERIC MYKERNEL # cd /usr/src # make buildkernel KERNCONF=MYKERNEL # make installkernel KERNCONF=MYKERNEL
要重建完全的操作系统:
# make buildworld # 构建完全的系统, 但不是内核 # make buildkernel # 使用 KERNCONF 配置文件编译内核 # make installkernel # reboot # mergemaster -p # 建立临时根环境并比对系统配置文件 # make installworld # mergemaster # 升级所有配置和其他文件 # reboot
对于源的一些小改动, 有时候简单的命令就足够了:
# make kernel world # 编译并安装内核和系统 # mergemaster # reboot
3. 进程
3.1. 进程列表
PID是每个进程唯一号码. 使用 ps 获取所有正在运行的进程列表.
# ps -auxefw # 所有正在运行进程的详尽列表 # ps axww | grep cron # ps aux | grep 'ss[h]' # Find all ssh pids without the grep pid # pgrep -l sshd # 查找所有进程名中有sshd的进程ID # echo $$ # The PID of your shell # fuser -va 22/tcp # 列出使用端口22的进程 # fuser -va /home # 列出访问 /home 分区的进程 # strace df # 跟踪系统调用和信号 # truss df # 同上(FreeBSD/Solaris/类Unix) # history | tail -50 # 显示最后50个使用过的命令
3.2. 优先级
用 renice 更改正在运行进程的优先级. 负值是更高的优先级, 最小为-20, 其正值与 "nice" 值的意义相同.
# renice -5 586 # 更强的优先级
使用 nice 命令启动一个已定义优先级的进程. 正值为低优先级, 负值为高优先级.
# nice -n -5 top # 更高优先级(/usr/bin/nice) # nice -n 5 top # 更低优先级(/usr/bin/nice) # nice +5 top # tcsh 内置 nice 命令(同上)
ionice 可以调度磁盘 IO.
# ionice c3 -p123 # 给 pid 123 设置为 idle 类型 # ionice -c2 -n0 firefox # 用 best effort 类型运行 firefox 并且设为高优先级 # ionice -c3 -p$$ # 将当前的进程(shell)的磁盘 IO 调度设置为 idle 类型
3.3. 前台/后台
当一个进程在 shell 中已运行, 可以使用 [Ctrl]-[Z] (^Z), bg 和 fg 来 调入调出前后台.
# ping cb.vu > ping.log
^Z (使用 [Ctrl]-[Z] 来暂停)
# bg # 调入后台继续运行 # jobs -l # 后台进程列表 # fg %2 # 让进程 2 返回到前台运行
使用 nohup 开启一个持续运行的进程直到 shell 被关闭(避免挂断).
# nohup ping -i 60 > ping.log &
3.4. Top
top 程序用来实时显示系统中各个进程的运行信息.
# top
当 top 在运行的时候, 按下 h 键会显示帮助画面. 常用键如下:
u [用户名]- 只显示属于此用户的进程. 使用 + 或者空白可以查看所有用户
k [PID]- 结束 PID 进程
1- 显示所有进程状态信息(只有Linux)
R- 将当前排序倒转
3.5. Kill命令与信号
使用 kill 或 killall 终止或发送一个信号给进程.
# ping -i 60 cb.vu > ping.log & # kill -s TERM 4712 # 同 kill -15 4712 # killall -1 httpd # 发送 HUP 信号终止进程 httpd # pkill -9 http # 发送 TERM 信号终止包含 http 的进程 # pkill -TERM -u www # 发送 TERM 信号终止 www 所有者进程 # fuser -k -TERM -m /home # 终止所有访问 /home 的进程(卸载该分区前)
下面是一些重要的信号:
- 1
- HUP (挂起)
- 2
- INT (中断)
- 3
- QUIT (退出)
- 9
- KILL (KILL 信号不能被捕捉, 不能被忽略. )
- 15
- TERM (软件终止信号)
4. 文件系统
4.1. 权限
用 chmod 和 chown 更改访问权限和所有权. 对于所有用户的默认掩码(umask)可以在 /etc/profile (Linux) 或 /etc/login.conf (FreeBSD) 中修改.
- 1 –x 执行
- 2 -w- 写
- 4 r– 读
# chmod [OPTION] MODE[,MODE] FILE # MODE 可以是 [ugoa]*([-+=]([rwxXst])) # chmod 640 /var/log/maillog # 更改 maillog 访问权限为 -rw-r----- # chmod u=rw,g=r,o= /var/log/maillog # 同上 # chmod -R o-r /home/* # 递归去除所有其他用户的可读权限 # chmod u+s /path/to/prog # 在可执行位设置 SUID (知道你在干什么!) # find / -perm -u+s -print # 查找所有设置过 SUID 位的程序 # chown user:group /path/to/file # 改变文件的所有者和文件关联的组 # chgrp group /path/to/file # 改变文件关联的组 # chmod 640 `find ./ -type f -print` # Change permissions to 640 for all files # chmod 751 `find ./ -type d -print` # Change permissions to 751 for all directories
4.2. 磁盘信息
# diskinfo -v /dev/ad2 # 显示磁盘信息(扇区/大小) (FreeBSD) # hdparm -I /dev/sda # 显示 IDE/ATA 磁盘信息 (Linux) # fdisk /dev/ad2 # 显示和修改磁盘分区表 # smartctl -a /dev/ad2 # 显示磁盘检测信息
4.3. Boot
4.3.1. FreeBSD
如果新内核不能引导, 要引导一个旧内核, 停止启动倒计时, 做如下动作:
# unload # load kernel.old # boot
4.4. 系统挂载点/磁盘使用情况
# mount | column -t # 显示系统已挂载分区情况 # df # 显示磁盘剩余空间和挂载的设备 # cat /proc/partitions # 显示所有设备的所有分区(Linux)
4.5. 磁盘使用情况
# du -sh * # 列出当前目录下所有文件夹大小 # du -csh # 当前目录下所有目录大小总数 # du -ks * | sort -n -r # 由大到小排序显示目录大小 # ls -lSr # 由小到大显示文件列表
4.6. 谁打开了那些文件
4.6.1. FreeBSD 和大多数 Unix
# fstat -f /home # 对于一个挂载点 # fstat -p PID # 对于一个应用程序进程 ID # fstat -u user # 对于一个用户 # ps ax | grep Xorg | awk '{print $1}' # fstat -p 1252 # find -x /var -inum 212042
4.6.2. Linux
# fuser -m /home # 列出访问 /home 的进程 # lsof /home # ps ax | grep Xorg | awk '{print $1}' # lsof -p 3324 # lsof /var/log/Xorg.0.log
4.7. 挂载/重挂载一个文件系统
举个 cdrom 的例子. 如果已经列于 /etc/fstab 中:
# mount /cdrom
4.7.1. FreeBSD
# mount -v -t cd9660 /dev/cd0c /mnt # cdrom # mount_cd9660 /dev/wcd0c /cdrom # 另外一个方法 # mount -v -t msdos /dev/fd0c /mnt # 软驱
/etc/fstab 中的一条:
# Device Mountpoint FStype Options Dump Pass# /dev/acd0 /cdrom cd9660 ro,noauto 0 0
要允许用户做这些, 可以这么做:
# sysctl vfs.usermount=1 # 或者在 /etc/sysctl.conf 中插入一条 "vfs.usermount=1"
4.7.2. Linux
# mount -t auto /dev/cdrom /mnt/cdrom # 典型的 cdrom 挂载命令 # mount /dev/hdc -t iso9660 -r /cdrom # IDE # mount /dev/sdc0 -t iso9660 -r /cdrom # SCSI
/etc/fstab 中的条目:
/dev/cdrom /media/cdrom subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec 0 0
用 Linux 挂载一个 FreeBSD 分区
# fdisk /dev/sda # 查找 FreeBSD 分区 # mount -t ufs -o ufstype=ufs2,ro /dev/sda3 /mnt
4.7.3. 重挂载
# mount -o remount,ro / # Linux # mount -o ro / # FreeBSD
从 cdrom 拷贝原始数据进一个 iso 映像文件:
# dd if=/dev/cd0c of=file.iso
4.7.4. 给即时烧录(on-the-fly)添加 swap
假设你需要很多的 swap (即刻), 如一个 2GB 文件 /swap2gb (只限 Linux).
# dd if=/dev/zero of=/swap2gb bs=1024k count=2000 # mkswap /swap2gb # 创建交换区 # swapon /swap2gb # 激活这个 swap. 现在可以使用了 # swapoff /swap2gb # 当使用完毕, 释放这个 swap # rm /swap2gb
4.8. 挂载一个 SMB 共享
4.8.1. Linux
# smbclient -U user -I 192.168.16.229 -L //smbshare/ # 列出共享 # mount -t smbfs -o username=winuser //smbserver/myshare /mnt/smbshare # mount -t cifs -o username=winuser,password=winpwd //192.168.16.229/myshare /mnt/share
此外, mount.cifs 软件包可以存储认证到一个文件中. 例如, /home/user/.smb:
username=winuser password=winpwd
现在可以像下面那样挂载:
# mount -t cifs -o credentials=/home/user/.smb //192.168.16.229/myshare /mnt/smbshare
4.8.2. FreeBSD
# smbutil view -I 192.168.16.229 //winuser@smbserver # 列出共享 # mount_smbfs -I 192.168.16.229 //winuser@smbserver/myshare /mnt/smbshare
4.9. 挂载镜像文件
4.9.1. Linux loop-back
# mount -t iso9660 -o loop file.iso /mnt # 挂载 CD 镜像文件 # mount -t ext3 -o loop file.img /mnt # 用 ext3 文件系统挂载镜像文件
4.9.2. FreeBSD
用于存储设备:
# mdconfig -a -t vnode -f file.iso -u 0 # mount -t cd9660 /dev/md0 /mnt # umount /mnt; mdconfig -d -u 0 # 清除 md 设备
用于虚拟节点:
# vnconfig /dev/vn0c file.iso; mount -t cd9660 /dev/vn0c /mnt # umount /mnt; vnconfig -u /dev/vn0c # 清除 vn 设备
4.9.3. Solaris and FreeBSD
用于 loop-back 文件接口或 lofi:
# lofiadm -a file.iso # mount -F hsfs -o ro /dev/lofi/1 /mnt # umount /mnt; lofiadm -d /dev/lofi/1 # 清除 lofi 设备
4.10. 创建并刻录 ISO 镜像文件
# dd if=/dev/hdc of=/tmp/mycd.iso bs=2048 conv=notrunc
使用 mkisofs 把目录中所有文件创建成 CD/DVD 镜像文件.
# mkisofs -J -L -r -V TITLE -o imagefile.iso /path/to/dir
4.11. 刻录 ISO 镜像文件
4.11.1. FreeBSD
FreeBSD 默认情况下没有在 ATAPI 驱动上启用 DMA.
# burncd -f /dev/acd0 data imagefile.iso fixate # ATAPI 驱动 # cdrecord -scanbus # 查找 burner 设备描述符(如 1,0,0) # cdrecord dev=1,0,0 imagefile.iso
4.11.2. Linux
# cdrecord dev=ATAPI -scanbus
然后同上面一样烧录 CD/DVD.
4.11.3. dvd+rw-tools
# growisofs -dvd-compat -Z /dev/dvd=imagefile.iso # 刻录已存在的 iso 镜像文件 # growisofs -dvd-compat -Z /dev/dvd -J -R /p/to/data # 直接刻录
4.11.4. 转换 Nero .nrg 文件成 .iso
# dd bs=1k if=imagefile.nrg of=imagefile.iso skip=300
4.11.5. 转换 bin/cue 镜像成 .iso
# bchunk imagefile.bin imagefile.cue imagefile.iso
4.12. 创建基于文件的镜像文件
4.12.1. FreeBSD
# dd if=/dev/random of=/usr/vdisk.img bs=1K count=1M # mdconfig -a -t vnode -f /usr/vdisk.img -u 0 # 创建设备 /dev/md1 # bsdlabel -w /dev/md0 # newfs /dev/md0c # mount /dev/md0c /mnt # umount /mnt; mdconfig -d -u 0; rm /usr/vdisk.img # 清除 md 设备
也可能在增加镜像文件的大小之后, 如增大到 300MB.
# umount /mnt; mdconfig -d -u 0 # dd if=/dev/zero bs=1m count=300 >> /usr/vdisk.img # mdconfig -a -t vnode -f /usr/vdisk.img -u 0 # growfs /dev/md0 # mount /dev/md0c /mnt # 文件分区现在为 300MB
4.12.2. Linux
# dd if=/dev/zero of=/usr/vdisk.img bs=1024k count=1024 # mkfs.ext3 /usr/vdisk.img # mount -o loop /usr/vdisk.img /mnt # umount /mnt; rm /usr/vdisk.img # 清楚
4.12.3. Linux with losetup
# dd if=/dev/urandom of=/usr/vdisk.img bs=1024k count=1024 # losetup /dev/loop0 /usr/vdisk.img # 创建并联结 /dev/loop0 # mkfs.ext3 /dev/loop0 # mount /dev/loop0 /mnt # losetup -a # 查看已经挂载的 loop 设备 # umount /mnt # losetup -d /dev/loop0 # Detach # rm /usr/vdisk.img
4.13. 创建基于内存的文件系统
4.13.1. FreeBSD
# mount_mfs -o rw -s 64M md /memdisk # umount /memdisk; mdconfig -d -u 0 # 清除该 md 设备
/etc/fstab 条目:
md /memdisk mfs rw,-s64M 0 0
4.13.2. Linux
# mount -t tmpfs -osize=64m tmpfs /memdisk
4.14. 磁盘性能
# time dd if=/dev/ad4s3c of=/dev/null bs=1024k count=1000 # time dd if=/dev/zero bs=1024k count=1000 of=/home/1Gb.file # hdparm -tT /dev/hda # 仅限 Linux
5. 网络
5.1. 调试
5.1.1. Linux
# ethtool eth0 # 显示以太网状态(replaces mii-diag) # ethtool -s eth0 speed 100 duplex full # 把网卡 eth0 速度改为 100兆/秒, 采用全双工 # ethtool -s eth0 autoneg off # 禁用自动协商模式 # ethtool -p eth1 # 闪烁网络接口 LED 灯 - 如果支持的话, 非常实用 # ip link show # 在 Linux 上显示所有网络接口(同 ifconfig 类似) # ip link set eth0 up # 使设备激活(或Down掉). 同 "ifconfig eth0 up" # ip addr show # 在 Linux 上显示所有 IP 地址(与 ifconfig 类似) # ip neigh show # 与 arp -a 类似
5.1.2. 其他系统
# ifconfig fxp0 # 查看 "media" 字段(FreeBSD) # arp -a # 查看路由(或主机) ARP 条目(所有系统) # ping cb.vu # 第一个要试的事情... # traceroute cb.vu # 列印到目的地的路由路径 # ifconfig fxp0 media 100baseTX mediaopt full-duplex # 100兆/秒 全双工(FreeBSD) # netstat -s # 对每个网络协议做系统级分析 # arping 192.168.16.254 # 在网络层上 Ping # tcptraceroute -f 5 cb.vu # 使用 tcp 替换 icmp 来跟踪, 透过防火墙
5.2. 路由
5.2.1. 列印路由表
# route -n # Linux 或使用 "ip route" # netstat -rn # Linux, BSD 和 UNIX # route print # Windows
5.2.2. 添加删除路由
- FreeBSD
# route add 212.117.0.0/16 192.168.1.1 # route delete 212.117.0.0/16 # route add default 192.168.1.1
永久的添加路由可在
/etc/rc.conf配置文件中设置:static_routes="myroute" route_myroute="-net 212.117.0.0/16 192.168.1.1"
- Linux
# route add -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.16.254 # ip route add 192.168.20.0/24 via 192.168.16.254 # 等同于上面命令 # route add -net 192.168.20.0 netmask 255.255.255.0 dev eth0 # route add default gw 192.168.51.254 # ip route add default via 192.168.51.254 dev eth0 # 等同于上面命令 # route delete -net 192.168.20.0 netmask 255.255.255.0
- Solaris
# route add -net 192.168.20.0 -netmask 255.255.255.0 192.168.16.254 # route add default 192.168.51.254 1 # 1 = 通过此路由跳数减 1 # route change default 192.168.50.254 1
- Windows
# Route add 192.168.50.0 mask 255.255.255.0 192.168.51.253 # Route add 0.0.0.0 mask 0.0.0.0 192.168.51.254
5.3. 配置额外的 IP 地址
5.3.1. Linux
# ifconfig eth0 192.168.50.254 netmask 255.255.255.0 # 第一个 IP # ifconfig eth0:0 192.168.51.254 netmask 255.255.255.0 # 第二个 IP # ip addr add 192.168.50.254/24 dev eth0 # 等价命令 # ip addr add 192.168.51.254/24 dev eth0 label eth0:1
5.3.2. FreeBSD
# ifconfig fxp0 inet 192.168.50.254/24 # 第一个 IP # ifconfig fxp0 alias 192.168.51.254 netmask 255.255.255.0 # 第二个 IP
永久条目设置在 /etc/rc.conf 中:
ifconfig_fxp0="inet 192.168.50.254 netmask 255.255.255.0" ifconfig_fxp0_alias0="192.168.51.254 netmask 255.255.255.0"
5.3.3. Solaris
# ifconfig hme0 plumb # 启用网卡 # ifconfig hme0 192.168.50.254 netmask 255.255.255.0 up # 第一个 IP # ifconfig hme0:1 192.168.51.254 netmask 255.255.255.0 up # 第二个 IP
5.4. 更改 MAC 地址
# ifconfig eth0 down # ifconfig eth0 hw ether 00:01:02:03:04:05 # Linux # ifconfig fxp0 link 00:01:02:03:04:05 # FreeBSD # ifconfig hme0 ether 00:01:02:03:04:05 # Solaris # sudo ifconfig en0 ether 00:01:02:03:04:05 # Mac OS X Tiger # sudo ifconfig en0 lladdr 00:01:02:03:04:05 # Mac OS X Leopard
5.5. 使用中的端口
监听打开的端口:
# netstat -an | grep LISTEN # lsof -i # 列出所有因特网连接(Linux) # socklist # 列出打开的 socket (Linux) # sockstat -4 # 使用 socket 的应用程序列表(FreeBSD) # netstat -anp --udp --tcp | grep LISTEN # Linux # netstat -tup # 列出活跃的连接(Linux) # netstat -tupl # 列出系统中正在监听的端口(Linux) # netstat -ano # Windows
5.6. 防火墙
5.6.1. Linux
# iptables -L -n -v # 状态信息 # iptables -P INPUT ACCEPT # 打开所有 # iptables -P FORWARD ACCEPT # iptables -P OUTPUT ACCEPT # iptables -Z # 把所有链的包及字节的计数器清空 # iptables -F # 清空所有链 # iptables -X # 删除所有链
5.6.2. FreeBSD
# ipfw show # 状态信息 # ipfw list 65535 # 如果显示 "65535 deny ip from any to any", 那防火墙已被禁用 # sysctl net.inet.ip.fw.enable=0 # 禁用 # sysctl net.inet.ip.fw.enable=1 # 启用
5.7. 路由 IP 转发
5.7.1. Linux
# cat /proc/sys/net/ipv4/ip_forward # 查看 IP 转发 0=禁用, 1=启用 # echo 1 > /proc/sys/net/ipv4/ip_forward
5.7.2. FreeBSD
# sysctl net.inet.ip.forwarding # 查看 IP 转发 0=禁用, 1=启用 # sysctl net.inet.ip.forwarding=1 # sysctl net.inet.ip.fastforwarding=1 # 专用路由器或防火墙
Permanent with entry in /etc/rc.conf:
gateway_enable="YES" # 如果主机是网关则设置为 YES.
5.7.3. Solaris
# ndd -set /dev/ip ip_forwarding 1 # 查看 IP 转发 0=禁用, 1=启用
5.8. NAT - 网络地址转换
5.8.1. Linux
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # 激活 NAT # iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 20022 -j DNAT \ --to 192.168.16.44:22 # 转发端口 20022 到内部 IP 端口(ssh) # iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 993:995 -j DNAT \ --to 192.168.16.254:993:995 # 转发 993-995 范围端口 # ip route flush cache # iptables -L -t nat # 查看 NAT 状态信息
5.8.2. FreeBSD
# natd -s -m -u -dynamic -f /etc/natd.conf -n fxp0
Or edit /etc/rc.conf with:
firewall_enable="YES" # 设置 YES 来启用防火墙功能 firewall_type="open" # 防火墙类型(看 /etc/rc.firewall) natd_enable="YES" # 启用 natd (如果 firewall_enable == YES). natd_interface="tun0" # 公共的网络接口或要使用的 IP 地址. natd_flags="-s -m -u -dynamic -f /etc/natd.conf"
端口转发:
# cat /etc/natd.conf same_ports yes use_sockets yes unregistered_only # redirect_port tcp insideIP:2300-2399 3300-3399 # 端口范围 redirect_port udp 192.168.51.103:7777 7777
5.9. DNS
在 unix 上, 对于所有的网络接口的 DNS 条目都存储在 /etc/resolv.conf 文件中.
nameserver 78.31.70.238 search sleepyowl.net intern.lab domain sleepyowl.net
检查系统域名:
# hostname -d # 等同于 dnsdomainname
5.9.1. Windows
# ipconfig /? # 显示帮助 # ipconfig /all # 显示所有信息包括 DNS # ipconfig /flushdns # 清除 DNS 缓存
5.9.2. 转发查询
# dig sleepyowl.net # dig MX google.com # dig @127.0.0.1 NS sun.com # 测试本地服务器 # dig @204.97.212.10 NS MX heise.de # 查询外部 # dig AXFR @ns1.xname.org cb.vu # 查看区传送(zone transfer) # host -t MX cb.vu # 获取邮件 MX 记录 # host -t NS -T sun.com # 通过 TCP 连接获取 NS 记录 # host -a sleepyowl.net # 获取所有
5.9.3. 反向查询
# dig -x 78.31.70.238 # host 78.31.70.238 # nslookup 78.31.70.238
5.9.4. /etc/hosts
单个主机可以配置于文件 /etc/hosts 来代替本地正在运行的 named 反向域名查询.
78.31.70.238 sleepyowl.net sleepyowl
5.10. DHCP
5.10.1. Linux
# dhcpcd -n eth0 # 触发更新(并不总是可以工作) # dhcpcd -k eth0 # 释放并关闭
租约(lease)的全部信息存储在: /var/lib/dhcpcd/dhcpcd-eth0.info
5.10.2. FreeBSD
# dhclient bge0
租约(lease)的全部信息存储在: /var/db/dhclient.leases.bge0
/etc/dhclient.conf:
# cat /etc/dhclient.conf interface "rl0" { prepend domain-name-servers 127.0.0.1; default domain-name "sleepyowl.net"; supersede domain-name "sleepyowl.net"; }
5.10.3. Windows
# ipconfig /renew # 更新所有适配器 # ipconfig /renew LAN # 更新名叫 "LAN" 的适配器 # ipconfig /release WLAN # 释放名叫 "WLAN" 的适配器
5.11. 通信量分析(Traffic analysis)
5.11.1. 用 tcpdump 嗅探(sniff)
# tcpdump -nl -i bge0 not port ssh and src \(192.168.16.121 or 192.168.16.54\) # tcpdump -l > dump && tail -f dump # 缓冲输出 # tcpdump -i rl0 -w traffic.rl0 # 把数据报文写入二进制文件 # tcpdump -r traffic.rl0 # 从文件读取数据报文(也可以使用 ethereal) # tcpdump port 80 # 两个经典命令 # tcpdump host google.com # tcpdump -i eth0 -X port \(110 or 143\) # 查看端口 110(POP) 或 143(IMAP)的数据报文 # tcpdump -n -i eth0 icmp # 只捕获 ping # tcpdump -i eth0 -s 0 -A port 80 | grep GET # -s 0 为全部包, -A 为 ASCII
5.11.2. 用 nmap 扫描
# nmap cb.vu # 扫描主机上所有保留的 TCP 端口 # nmap -sP 192.168.16.0/24 # 找出在 0/24 上主机所使用的 IP # nmap -sS -sV -O cb.vu # 做秘密 SYN 扫描来探测系统和系统服务的版本信息
5.12. 流量控制(QoS)
5.12.1. 上传限制
- Linux
# tc qdisc add dev eth0 root tbf rate 480kbit latency 50ms burst 1540 # tc -s qdisc ls dev eth0 # 状态 # tc qdisc del dev eth0 root # 删除队列 # tc qdisc change dev eth0 root tbf rate 220kbit latency 50ms burst 1540
- FreeBSD
# kldload dummynet # 如有必要加载这个模块 # ipfw pipe 1 config bw 500Kbit/s # 创建一个带宽限制的 pipe # ipfw add pipe 1 ip from me to any # 转移所有上传进入这个 pipe
5.12.2. 服务质量 (Quality of service)
- Linux
# 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 # tc qdisc add dev eth0 parent 1:1 handle 10: sfq # tc qdisc add dev eth0 parent 1:2 handle 20: sfq # tc qdisc add dev eth0 parent 1:3 handle 30: sfq # tc filter add dev eth0 protocol ip parent 1: prio 1 u32 \ match ip dport 10000 0x3C00 flowid 1:1 # 使用服务端端口范围 match ip dst 123.23.0.1 flowid 1:1 # 或/和使用服务器 IP
- FreeBSD
# ipfw pipe 1 config bw 500Kbit/s # ipfw queue 1 config pipe 1 weight 100 # ipfw queue 2 config pipe 1 weight 10 # ipfw queue 3 config pipe 1 weight 1 # ipfw add 10 queue 1 proto udp dst-port 10000-11024 # ipfw add 11 queue 1 proto udp dst-ip 123.23.0.1 # 或/和使用服务器 IP # ipfw add 20 queue 2 dsp-port ssh # ipfw add 30 queue 3 from me to any # 剩余所有
5.13. NIS 调试
# ypwhich # 获取提供 NIS 服务的服务器名 # domainname # 已配置的 NIS 域名 # ypcat group # 列印 NIS 映射 group # cd /var/yp && make # 重建 yp 数据库 # ps auxww | grep ypbind # yppoll passwd.byname # cat /etc/yp.conf
6. SSH SCP
6.1. Public key authentication
# ssh-keygen -t dsa -N '' # cat ~/.ssh/id_dsa.pub | ssh you@host-server "cat - >> ~/.ssh/authorized_keys2"
6.1.1. 使用来自 ssh.com 的 Windows 客户端
# cd ~/.ssh # ssh-keygen -i -f keyfilename.pub >> authorized_keys2
6.1.2. 在 Windows 上使用 Putty
# scp .ssh/puttykey.pub root@192.168.51.254:.ssh/ # cd ~/.ssh # ssh-keygen -i -f puttykey.pub >> authorized_keys2
6.2. 检查指纹
# ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub # RSA 密钥 # ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub # DSA 密钥(默认) # ssh linda
6.3. 安全文件传输
# scp file.txt host-two:/tmp # scp joe@host-two:/www/*.html /www/tmp # scp -r joe@host-two:/www /www/tmp
在 Konqueror 或 Midnight 控制台中, 用地址 fish://user@gate 来访问远程文件系统是可行的, 就是比较慢而已.
6.4. 隧道(Tunneling)
# ssh -L localport:desthost:destport user@gate # gate 为目标主机网关 # ssh -R destport:desthost:localport user@gate # 转发你的 localport 到目标端口 # ssh -X user@gate # 转发 X 程序
6.4.1. 在 gate 上直接转发
# ssh -L 2401:localhost:2401 -L 8080:localhost:80 user@gate
6.4.2. 转发 Netbios 和远程桌面到第二个服务器
# ssh -L 139:smbserver:139 -L 3388:smbserver:3389 user@gate
6.4.3. 在 NAT 后面连接两个客户端
开启 cliuser 客户端(从目标到 gate):
# ssh -R 2022:localhost:22 user@gate # 转发客户端 22 端口到 gate:2022 端口
开启 cliadmin 客户端(从主机到 gate):
# ssh -L 3022:localhost:2022 admin@gate # 转发客户端 3022 端口到 gate:2022 端口
现在 admin 可以直接连接 cliuser 客户端:
# ssh -p 3022 admin@localhost # local:3022 -> gate:2022 -> client:22
6.4.4. 在 NAT 后面的 VNC 连接
开启 cliwin 客户端到 gate:
# ssh -R 15900:localhost:5900 user@gate
开启 cliadmin 客户端(从主机到 gate):
# ssh -L 5900:localhost:15900 admin@gate
现在 admin 直接连接到 VNC 客户端:
# vncconnect -display :0 localhost
7. 使用 SSH 建立 VPN
7.1. 单个 P2P 连接
7.1.1. 连接到服务端
Linux上的服务端:
cli># ssh -w5:5 root@hserver srv># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # 在服务端 shell 上执行
FreeBSD上的服务端:
cli># ssh -w5:5 root@hserver srv># ifconfig tun5 10.0.1.1 10.0.1.2 # 在服务端 shell 上执行
7.1.2. 连接到客户端
cli># ifconfig tun5 10.0.1.2 netmask 255.255.255.252 # Linux上的客户端 cli># ifconfig tun5 10.0.1.2 10.0.1.1 # FreeBSD上的客户端
7.2. 连接两个网络
7.2.1. 连接 gateA 到 gateB
Linux 上的 gateB:
gateA># ssh -w5:5 root@gateB gateB># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # 在 gateB 的 shell 中执行 gateB># route add -net 192.168.51.0 netmask 255.255.255.0 dev tun5 gateB># echo 1 > /proc/sys/net/ipv4/ip_forward # 如果不是默认网关 gateB># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
FreeBSD 上的 gateB:
gateA># ssh -w5:5 root@gateB # 创建 tun5 设备 gateB># ifconfig tun5 10.0.1.1 10.0.1.2 # 在 gateB 的 shell 中执行 gateB># route add 192.168.51.0/24 10.0.1.2 gateB># sysctl net.inet.ip.forwarding=1 # 如果不是默认网关 gateB># natd -s -m -u -dynamic -n fxp0 # 看 NAT gateA># sysctl net.inet.ip.fw.enable=1
7.2.2. 配置 gateA
Linux 上的 gateA:
gateA># ifconfig tun5 10.0.1.2 netmask 255.255.255.252 gateA># route add -net 192.168.16.0 netmask 255.255.255.0 dev tun5 gateA># echo 1 > /proc/sys/net/ipv4/ip_forward gateA># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
FreeBSD 上的 gateA:
gateA># ifconfig tun5 10.0.1.2 10.0.1.1 gateA># route add 192.168.16.0/24 10.0.1.2 gateA># sysctl net.inet.ip.forwarding=1 gateA># natd -s -m -u -dynamic -n fxp0 # 看 NAT gateA># sysctl net.inet.ip.fw.enable=1
8. RSYNC
# rsync -a /home/colin/ /backup/colin/ # rsync -a /var/ /var_bak/ # rsync -aR --delete-during /home/user/ /backup/ # 使用相对路径(看下面) # rsync -axSRzv /home/user/ user@server:/backup/user/ # rsync -azR --exclude /tmp/ /home/user/ user@server:/backup/ # rsync -az -e 'ssh -p 20022' /home/colin/ user@server:/backup/colin/ # rsync -axSRz /home/ ruser@hostname::rmodule/backup/ # rsync -axSRz ruser@hostname::rmodule/backup/ /home/ # 回拷贝
一些重要选项:
-a, --archive- 归档模式, 等于 -rlptgoD (非 -H)
-r, --recursive- 对子目录以递归模式处理
-R, --relative- 使用相对路径名
-H, --hard-links- 保留硬链结
-S, --sparse- 对稀疏文件进行特殊处理以节省DST的空间
-x, --one-file-system- 不跨越文件系统边界
--exclude=PATTERN- 指定排除不需要传输的文件模式
--delete-during- 传输期间删除
--delete-after- 传输结束以后再删除
8.1. 在 Windows 上使用 Rsync
8.1.1. 公钥认证
# ssh-keygen -t dsa -N '' # 创建密钥对 # rsync user@server:.ssh/authorized_keys2 . # 从服务器拷贝本地文件 # cat id_dsa.pub >> authorized_keys2 # 或者使用编辑器添加这个公钥 # rsync authorized_keys2 user@server:.ssh/ # 拷贝文件回服务器 # del authorized_keys2 # 删除本地拷贝
现在测试一下(在同一行里面):
rsync -rv "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \ 'user@server:My\ Documents/'
8.1.2. 自动备份
创建批处理文件 backup.bat
@ECHO OFF REM rsync the directory My Documents SETLOCAL SET CWRSYNCHOME=C:\PROGRAM FILES\CWRSYNC SET CYGWIN=nontsec SET CWOLDPATH=%PATH% REM uncomment the next line when using cygwin SET PATH=%CWRSYNCHOME%\BIN;%PATH% echo Press Control-C to abort rsync -av "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \ 'user@server:My\ Documents/' pause
9. SUDO
# sudo /etc/init.d/dhcpd restart # 用 root 权限运行 rc 脚本 # sudo -u sysadmin whoami # 使用其他用户运行命令
9.1. 配置
Sudo 的配置在 /etc/sudoers 中, 并且只能用 visudo 编辑.
下面是 sudoers 例子:
# cat /etc/sudoers # 主机别名 Host_Alias DMZ = 212.118.81.40/28 Host_Alias DESKTOP = work1, work2 # 用户别名 和 runas 别名 User_Alias ADMINS = colin, luca, admin User_Alias DEVEL = joe, jack, julia Runas_Alias DBA = oracle,pgsql # 命令别名, 其值为全路径命令 Cmnd_Alias SYSTEM = /sbin/reboot,/usr/bin/kill,/sbin/halt,/sbin/shutdown,/etc/init.d/ Cmnd_Alias PW = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root # Not root pwd! Cmnd_Alias DEBUG = /usr/sbin/tcpdump,/usr/bin/wireshark,/usr/bin/nmap # 一个真实的规则 root,ADMINS ALL = (ALL) NOPASSWD: ALL # ADMINS 别名中的用户可做任何事情不需要密码 DEVEL DESKTOP = (ALL) NOPASSWD: ALL # 开发人员可在 DESKTOP 别名的主机上做任何事情 DEVEL DMZ = (ALL) NOPASSWD: DEBUG # 开发人员可以在 DMZ 别名的主机上使用 DEBUG 别名中的命令 # 用户 sysadmin 可以在 DMZ 服务器上执行一些命令 sysadmin DMZ = (ALL) NOPASSWD: SYSTEM,PW,DEBUG sysadmin ALL,!DMZ = (ALL) NOPASSWD: ALL # 可以在非 DMZ 主机上做任何事情 %dba ALL = (DBA) ALL # 用户组 dba 可以运行 DBA 别名中用户权限的所有命令 # 所有用户可以在 DESKTOP 别名的主机上 挂载/卸载 CD-ROM ALL DESKTOP = NOPASSWD: /sbin/mount /cdrom,/sbin/umount /cdrom
10. 文件加密
10.1. 单个文件
加密和解密:
# openssl des -salt -in file -out file.des # openssl des -d -salt -in file.des -out file
10.2. 归档并加密整个目录
# tar -cf - directory | openssl des -salt -out directory.tar.des # 加密 # openssl des -d -salt -in directory.tar.des | tar -x # 解密
10.3. 压缩归档并加密整个目录
# tar -zcf - directory | openssl des -salt -out directory.tar.gz.des # 加密 # openssl des -d -salt -in directory.tar.gz.des | tar -xz # 解密
10.4. GPG
# gpg -c file # 使用密码加密文件 # gpg file.gpg # 文件解密(选项 -o 其他文件)
10.4.1. 使用密钥
# gpg --gen-key # 这需要一些时间
常用选项的简短描述:
-e- 加密数据
-d- 解密数据
-r- 为某个收件者加密('全名' 或者 'email@domain')
-a- 输出经过 ascii 封装的密钥
-o- 指定输出文件
- 只用于个人的加密
# gpg -e -r 'Your Name' file # 使用你的公钥加密 # gpg -o file -d file.gpg # 解密. 使用 -o 指定输出文件
- 用密钥加密-解密
# gpg -a -o alicekey.asc --export 'Alice' # Alice 导出她的公钥到 ascii 文件中 # gpg --send-keys --keyserver subkeys.pgp.net KEYID # Alice 把她的公钥放入一个服务器 # gpg --import alicekey.asc # 你导入她的密钥到你的公钥环(pubring)中 # gpg --search-keys --keyserver subkeys.pgp.net 'Alice' # 或者从一个服务器中获取他的公钥 # gpg -e -r 'Alice' file # 给 Alice 加密文件 # gpg -d file.gpg -o file # 解密 Alice 给你的加密文件
- 密钥管理
# gpg --list-keys # 列出所有公钥并查看其 KEYID # gpg --gen-revoke 'Your Name' # 产生一份撤销密钥证书 # gpg --list-secret-keys # 列出所有私钥 # gpg --delete-keys NAME # 从本的密钥环中删除一个公钥 # gpg --delete-secret-key NAME # 从本的密钥环中删除一个私钥 # gpg --fingerprint KEYID # 显示 KIYID 这个密钥的指纹 # gpg --edit-key KEYID # 编辑密钥(比如签名或者添加/删除 email)
11. 分区加密
11.1. Linux
11.1.1. dm-crypt with LUKS
- 创建加密分区
# dd if=/dev/urandom of=/dev/sdc1 # 可选 # cryptsetup -y luksFormat /dev/sdc1 # 这破坏了在 sdc1 上的数据 # cryptsetup luksOpen /dev/sdc1 sdc1 # mkfs.ext3 /dev/mapper/sdc1 # 创建 ext3 文件系统 # mount -t ext3 /dev/mapper/sdc1 /mnt # umount /mnt # cryptsetup luksClose sdc1 # Detach 已加密的分区
- Attach
# cryptsetup luksOpen /dev/sdc1 sdc1 # mount -t ext3 /dev/mapper/sdc1 /mnt
- Detach
# umount /mnt # cryptsetup luksClose sdc1
11.1.2. dm-crypt without LUKS
# cryptsetup -y create sdc1 /dev/sdc1 # 或任何其他分区像 /dev/loop0 # dmsetup ls # 检查一下, 将显示: sdc1 (254, 0) # mkfs.ext3 /dev/mapper/sdc1 # 只有第一次要这么做! # mount -t ext3 /dev/mapper/sdc1 /mnt # umount /mnt/ # cryptsetup remove sdc1 # Detach 已加密的分区
11.2. FreeBSD
11.2.1. 使用密码和密钥
- 创建加密分区
# dd if=/dev/random of=/root/ad1.key bs=64 count=1 # 加密主密钥的密钥 # geli init -s 4096 -K /root/ad1.key /dev/ad1 # 对于磁盘也可用 -s 8192 # geli attach -k /root/ad1.key /dev/ad1 # 将 /dev/ad1 与所生成的密钥 /root/ad1.key 关联 # dd if=/dev/random of=/dev/ad1.eli bs=1m # 可选, 需要很长时间 # newfs /dev/ad1.eli # 创建文件系统 # mount /dev/ad1.eli /mnt
- Attach
# geli attach -k /root/ad1.key /dev/ad1 # fsck -ny -t ffs /dev/ad1.eli # 检查文件系统 # mount /dev/ad1.eli /mnt
- Detach
# umount /mnt # geli detach /dev/ad1.eli
11.2.2. 仅用密码
# dd if=/dev/zero of=/cryptedfile bs=1M count=1000 # 1 GB 文件 # mdconfig -at vnode -f /cryptedfile # geli init /dev/md0 # 仅用密码加密 # geli attach /dev/md0 # newfs -U -m 0 /dev/md0.eli # mount /dev/md0.eli /mnt # umount /dev/md0.eli # geli detach md0.eli
现在可以把这个映像文件加载成仅需密码的文件系统.
# mdconfig -at vnode -f /cryptedfile # geli attach /dev/md0 # mount /dev/md0.eli /mnt
12. SSL 认证
12.1. 步骤
- 我们需要一个证书颁发机构来签署我们的证书.
- 创建一个证书签发申请(signing request).
- 证书颁发机构签署证书.
- 如果有需要, 加入证书和密钥到单个文件来给应用程序使用.
12.2. 配置 OpenSSL
确保所有目录已经创建:
# mkdir -p /usr/local/certs/CA # cd /usr/local/certs/CA # mkdir certs crl newcerts private # echo "01" > serial # 仅当 serial 不存在时 # touch index.txt
12.3. 创建一个认证授权
# openssl req -new -x509 -days 730 -config /etc/ssl/openssl.cnf \ -keyout CA/private/cakey.pem -out CA/cacert.pem
12.4. 创建证书签发申请
# openssl req -new -keyout newkey.pem -out newreq.pem \ -config /etc/ssl/openssl.cnf # openssl req -nodes -new -keyout newkey.pem -out newreq.pem \ -config /etc/ssl/openssl.cnf # 不对这个密钥加密
12.5. 签署证书
# cat newreq.pem newkey.pem > new.pem # openssl ca -policy policy_anything -out servernamecert.pem \ -config /etc/ssl/openssl.cnf -infiles new.pem # mv newkey.pem servernamekey.pem
12.6. 创建联合认证(united certificate)
最后 servername.pem 文件应该看起来像这样:
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDutWy+o/XZ/[...]qK5LqQgT3c9dU6fcR+WuSs6aejdEDDqBRQ -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIERzCCA7CgAwIBAgIBBDANB[...]iG9w0BAQQFADCBxTELMAkGA1UEBhMCREUx -----END CERTIFICATE-----
12.7. 查看证书信息
# openssl x509 -text -in servernamecert.pem # 显示证书信息 # openssl req -noout -text -in server.csr # 显示申请信息 # openssl s_client -connect cb.vu:443 # 检查 web 服务器认证信息
13. CVS
13.1. 服务器设置
13.1.1. CVS 环境初始化
# mkdir -p /usr/local/cvs # setenv CVSROOT /usr/local/cvs # 设置 CVSROOT 环境变量(本地) # cvs init # 创建所有初始化 CVS 配置文件 # cd /root # cvs checkout CVSROOT # 签出配置文件来修改他们 # cd CVSROOT # cvs commit config # cvs add writers # 添加文件 writers 进 repository # cvs edit checkoutlist # cvs commit # 提交所有配置更改
13.1.2. 用 inetd 设置网络
在 /etc/inetd.conf 中配置如下行:
cvspserver stream tcp nowait cvs /usr/bin/cvs cvs \
--allow-root=/usr/local/cvs pserver
13.1.3. 单独认证
# htpasswd -cb passwd user1 password1 # -c 创建文件 # htpasswd -b passwd user2 password2
它看起来像这样:
# cat passwd user1:xsFjhU22u8Fuo:cvs user2:vnefJOsnnvToM:cvs
13.2. 测试它
# cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs login
13.3. CVSROOT 变量
# setenv CVSROOT :pserver:<username>@<host>:/cvsdirectory # setenv CVSROOT /usr/local/cvs # 仅限本的使用 # setenv CVSROOT :local:/usr/local/cvs # 同上 # setenv CVSROOT :ext:user@cvsserver:/usr/local/cvs # 通过 SSH 直接访问 # setenv CVS_RSH ssh # ext 协议访问 # setenv CVSROOT :pserver:user@cvsserver.254:/usr/local/cvs # 通过 pserver 网络访问
13.4. 通过 SSH 隧道访问 CVS
在 shell 1:
# ssh -L2401:localhost:2401 colin@cvs_server # ssh -L2401:cvs_server:2401 colin@gateway
在 shell 2:
# setenv CVSROOT :pserver:colin@localhost:/usr/local/cvs # cvs login # cvs checkout MyProject/src
13.5. CVS 命令及其使用
13.5.1. 导入
# cvs import [options] directory-name vendor-tag release-tag # cd /devel # cvs import myapp Company R1_0
13.5.2. 签出, 更新和提交
# cvs co myapp/tools # 仅会签出 tools 目录 # cvs co -r R1_1 myapp # 签出修订版本为 R1_1 的 myapp (sticky) # cvs -q -d update -P # 典型的 CVS 更新 # cvs update -A # 重置所有 sticky 标签(或日期, 选项) # cvs add newfile # 添加一个新文件 # cvs add -kb newfile # 添加一个二进制文件 # cvs commit file1 file2 # 仅提交这两个文件 # cvs commit -m "message" # 提交所有更改并为这个更改添加日志消息
13.5.3. 创建一个 patch
# cd /devel/project # diff -Naur olddir newdir > patchfile # diff -Naur oldfile newfile > patchfile
13.5.4. 应用一个 patch
# cd /devel/project # patch --dry-run -p0 < patchfile # Test the path without applying it # patch -p0 < patchfile # patch -p1 < patchfile # strip off the 1st level from the path
14. SVN
14.1. Server setup
# svnadmin create --fs-type fsfs /home/svn/project1
访问方式:
file://- Direct file system access
svn://orsvn+ssh://- Remote access with the svnserve server
http://- Remote access with webdav using apache.
# svn import /project1/ file:///home/svn/project1/trunk -m 'Initial import' # svn checkout file:///home/svn/project1
14.2. Remote access with ssh
# svn checkout svn+ssh://hostname/home/svn/project1
# groupadd subversion # groupmod -A user1 subversion # chown -R root:subversion /home/svn # chmod -R 770 /home/svn
14.3. Remote access with http (apache)
Apache 配置:
LoadModule dav_module modules/mod_dav.so LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so <Location /svn> DAV svn SVNParentPath /home/svn AuthType Basic AuthName "Subversion repository" AuthzSVNAccessFile /etc/apache2/svn.acl AuthUserFile /etc/apache2/svn-passwd Require valid-user </Location>
# chown -R www:www /home/svn # htpasswd -c /etc/svn-passwd user1
Access control svn.acl example:
[/] * = r [groups] project1-developers = joe, jack, jane [project1:] @project1-developers = rw
14.4. SVN commands and usage
14.4.1. Import
# svn help import # svn import /project1/newdir http://host.url/svn/project1/trunk/src -m 'add newdir'
14.4.2. Typical SVN commands
# svn co http://host.url/svn/project1/trunk # svn mkdir http://host.url/svn/project1/tags/ # svn copy -m "Tag rc1 rel." http://host.url/svn/project1/trunk \ http://host.url/svn/project1/tags/1.0rc1 # svn status [--verbose] # svn add src/file.h src/file.cpp # svn commit -m 'Added new class file' # svn ls http://host.url/svn/project1/tags/ # svn move foo.c bar.c # svn delete some_old_file
15. 实用命令
15.1. less
# less unixtoolbox.xhtml
h, H- 显示指令的汇总列表
f, ^F, ^V, SPACE- 向前滚动一屏
b, ^B, ESC-v- 向后滚动一屏
F- 向前滚动; 类似于"tail -f"
/- pattern 向前搜索
?- pattern 向后搜索
n- 重复之前的搜索
N- 反方向重复之前的搜索
q- 退出
15.2. vi
15.2.1. Quit
:w newfilename- 保存文件为 newfilename
:wq or :x- 保存并退出
:q!- 退出但不保存
15.2.2. 移动和查找
/- string 向前查找 string
?- string 向后查找 string
n- 同方向重复上一次搜索命令
N- 反方向重复上一次搜索命令
{- 光标移至段落结尾
}- 光标移至段落开头
1G- 光标移至文件的第一行首
nG- 光标移至文件的第 n 行首
G- 光标移至文件的最后一行首
:%s/OLD/NEW/g- 替换所有查找到的 OLD 为 NEW
15.2.3. 删除文本
dd- 删除当前行
D- 删除光标到当前行末尾的字符
dw- 删除单词
x- 删除字符
u- 回复上一次操作
U- 回复所有此行的更改
15.3. mail
# mail c@cb.vu Subject: Your text is full of typos "For a moment, nothing happened. Then, after a second or so, nothing continued to happen." . EOT # # echo "This is the mail body" | mail c@cb.vu
15.4. tar
15.4.1. 创建
# cd / # tar -cf home.tar home/ # 归档整个 /home 目录(c 为创建) # tar -czf home.tgz home/ # 等同于 zip 压缩 # tar -cjf home.tbz home/ # 等同于 bzip2 压缩 # tar -C /usr -czf local.tgz local/etc local/www # tar -C /usr -xzf local.tgz # 释放 local 目录到 /usr # cd /usr; tar -xzf local.tgz # 同上面一样
15.4.2. 释放(Extract)
# tar -tzf home.tgz # 列出归档文件中的所有文件, 并不释放 # tar -xf home.tar # 释放归档文件(x 为释放) # tar -xzf home.tgz # 等同于 zip 压缩 # tar -xjf home.tgz # 等同于 bzip2 压缩 # tar -xjf home.tgz home/colin/file.txt # 释放单个文件
15.4.3. 更高级的
# tar c dir/ | gzip | ssh user@remote 'dd of=dir.tgz' # 归档压缩 dir/ 目录并存储到远程主机上 # tar cvf - `find . -print` > backup.tar # 归档当前目录 # tar -cf - -C /etc . | tar xpf - -C /backup/etc # 拷贝目录 # tar -cf - -C /etc . | ssh user@remote tar xpf - -C /backup/etc # 远程拷贝 # tar -czf home.tgz --exclude '*.o' --exclude 'tmp/' home/
15.5. dd
15.5.1. 备份和恢复
# dd if=/dev/hda of=/dev/hdc bs=16065b # 拷贝磁盘到磁盘(相同大小) # dd if=/dev/sda7 of /home/root.img bs=4096 conv=notrunc,noerror # 备份 / # dd if /home/root.img of=/dev/sda7 bs=4096 conv=notrunc,noerror # 恢复 / # dd bs=1M if=/dev/ad4s3e | gzip -c > ad4s3e.gz # 压缩备份 # gunzip -dc ad4s3e.gz | dd of=/dev/ad0s3e bs=1M # 解压恢复 # dd bs=1M if=/dev/ad4s3e | gzip | ssh eedcoba@fry 'dd of=ad4s3e.gz' # 也可为远程的 # gunzip -dc ad4s3e.gz | ssh eedcoba@host 'dd of=/dev/ad0s3e bs=1M' # dd if=/dev/ad0 of=/dev/ad2 skip=1 seek=1 bs=4k conv=noerror # 忽略 MBR
15.5.2. 恢复
# dd if=/dev/hda of=/dev/null bs=1m # 检查坏扇区 # dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc | gzip | ssh \ # 发送到远程 root@fry 'dd of=hda1.gz bs=1k' # dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc of=hda1.img # 存储为一个映像文件 # mount -o loop /hda1.img /mnt # 挂载这个映像文件 # rsync -ax /mnt/ /newdisk/ # 拷贝到一个新磁盘 # dd if=/dev/hda of=/dev/hda # 刷新磁状态
15.5.3. 删除
# dd if=/dev/zero of=/dev/hdc # 删除全部数据 # dd if=/dev/urandom of=/dev/hdc # 更好的删除全部数据 # kill -USR1 PID # 查看 dd 进度(仅Linux!)
15.5.4. MBR 技巧
# dd if=/dev/sda of=/mbr_sda.bak bs=512 count=1 # 完全备份 MBR # dd if=/dev/zero of=/dev/sda bs=512 count=1 # 删除 MBR 和分区表 # dd if=/mbr_sda.bak of=/dev/sda bs=512 count=1 # 完全恢复MBR # dd if=/mbr_sda.bak of=/dev/sda bs=446 count=1 # 仅回复引导程序 # dd if=/mbr_sda.bak of=/dev/sda bs=1 count=64 skip=446 seek=446 # 恢复分区表
15.6. screen
15.6.1. 简短实例
# screen # top
现在用 Ctrl-a Ctrl-d 来 detach. Reattach 终端:
# screen -r # screen -R -D
15.6.2. Screen 命令 (在 screen 中)
Ctrl-a ?- 各功能的帮助摘要
Ctrl-a c- 创建一个新的 window (终端)
Ctrl-a Ctrl-n和Ctrl-a Ctrl-p- 切换到下一个或前一个 window
Ctrl-a Ctrl-N- N 为 0 到 9 的数字, 用来切换到相对应的 window
Ctrl-a "- 获取所有正在运行的 window 的可导航的列表
Ctrl-a a- 清楚错误的 Ctrl-a
Ctrl-a Ctrl-d- 断开所有会话, 会话中所有任务运行于后台
Ctrl-a x- 用密码锁柱 screen 终端
15.7. Find
# find . -type f ! -perm -444 # 寻找所有无法读取的文件 # find . -type d ! -perm -111 # 寻找所有无法访问的目录 # find /home/user/ -cmin 10 -print # 寻找最后 10 分钟创建或修改的文件 # find . -name '*.[ch]' | xargs grep -E 'expr' # 在当前目录及子目录搜索 'expr' 表达式 # find / -name "*.core" | xargs rm # 寻找 core 垃圾并删除它们(也可试试 core.*) # find / -name "*.core" -print -exec rm {} \; # 另一种语法 # find . \( -iname "*.png" -o -iname "*.jpg" \) -print -exec tar -rf images.tar {} \; # find . -type f -name "*.txt" ! -name README.txt -print # 除 README.txt 的文件 # find /var/ -size +10M -exec ls -lh {} \; # 查找 > 10 MB 的文件 # find /var/ -size +10M -ls # 这个更简单 # find . -size +10M -size -50M -print # find /usr/ports/ -name work -type d -print -exec rm -rf {} \; # 清理 port # find / -type f -user root -perm -4000 -exec ls -l {} \; # find . -type f | xargs ls -l # 不能工作于有空格的名字 # find . -type f -print0 | xargs -0 ls -l # 可工作于有空格的名字 # find . -type f -exec ls -l '{}' \; # 或使用用于 -exec 的引用 '{}'
15.8. 混杂的
# which command # 显示命令的全路径名 # time command # 显示一个命令执行完成所用的时间 # time cat # 使用 time 作为秒表, 用 Ctrl-c 来停止 # set | grep $USER # 列显当前环境变量 # cal -3 # 显示三个月日历 # date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] # date 10022155 # 设置日期和时间 # whatis grep # 显示命令的简短信息 # whereis java # 查询命令的的路径和标准目录 # setenv varname value # 设置环境变量, 设置变量 varname 的值为 value (csh/tcsh) # export varname="value" # 设置环境变量, 设置变量 varname 的值为 value (sh/ksh/bash) # pwd # 显示当前工作目录 # mkdir -p /path/to/dir # 如果存在不显示错误, 建立所需的上级目录 # mkdir -p project/{bin,src,obj,doc/{html,man,pdf},debug/some/more/dirs} # rmdir /path/to/dir # 移除目录 # rm -rf /path/to/dir # 移除目录和其内容(强制) # cp -la /dir1 /dir2 # 存档, 硬连接目录所有文件, 用来替代拷贝 # cp -lpR /dir1 /dir2 # 同上 (FreeBSD) # cp unixtoolbox.xhtml{,.bak} # 拷贝文件成新扩展名的快速方法 # mv /dir1 /dir2 # 修改目录名
16. 软件安装
16.1. 列出已安装过的软件包
# rpm -qa # 列出已安装过的软件包(RH, SuSE, 基于 RPM 的) # dpkg -l # Debian, Ubuntu # pkg_info # 列出所有已安装过的软件包(FreeBSD) # pkg_info -W smbd # 查看 smbd 安装了那些软件包(FreeBSD) # pkginfo # Solaris
16.2. 添加/删除软件
# rpm -i pkgname.rpm # 安装软件包(RH, SuSE, 基于 RPM 的) # rpm -e pkgname # 删除软件包
16.2.1. Debian
# apt-get update # 更新源列表 # apt-get install emacs # 安装 emacs 软件包 # dpkg --remove emacs # 删除 emacs 软件包 # dpkg -S file # 查找拥有该 file 的软件包
16.2.2. Gentoo
# emerge --sync # 同步更新本地 protage 树 # emerge -u packagename # 安装或更新一个软件包 # emerge -C packagename # 删除软件包 # revdep-rebuild # 修复依赖关系的缺失
16.2.3. Solaris
# pkgadd -d <cdrom>/Solaris_9/Product SUNWgtar # pkgadd -d SUNWgtar # 添加下载的软件包(先要 bunzip2) # pkgrm SUNWgtar # 删除软件包
16.2.4. FreeBSD
# pkg_add -r rsync # 获取并安装 rsync # pkg_delete /var/db/pkg/rsync-xx # 删除 rsync 软件包
16.2.5. FreeBSD ports
# portsnap fetch extract # 当第一次运行这个命令, 会创建 port 树 # portsnap fetch update # 跟新 port 树 # cd /usr/ports/net/rsync/ # 选择软件安装目录 # make install distclean # 安装并清理(也可看 man ports) # make package # Make 一个二进制软件包
16.2.6. 库路径
# ldd /usr/bin/rsync # 列出所有所需的运行时库 # ldconfig -n /path/to/libs/ # 添加一个路径到共享库目录Add a path to the shared libraries directories # ldconfig -m /path/to/libs/ # FreeBSD
17. 媒体转换
17.1. 文本编码
# iconv -f <from_encoding> -t <to_encoding> <input_file> # iconv -f ISO8859-1 -t UTF-8 -o file.input > file_utf8 # iconv -l # 列显系统所支持的字符编码
17.2. Unix - DOS 新行
# sed 's/.$//' dosfile.txt > unixfile.txt # sed -n p unixfile.txt > dosfile.txt
17.3. PDF 转换成 Jpeg 和 连接一串 PDF 文件
# gs -dBATCH -dNOPAUSE -sDEVICE=jpeg -r150 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \ -dMaxStripSize=8192 -sOutputFile=unixtoolbox_%d.jpg unixtoolbox.pdf # convert unixtoolbox.pdf unixtoolbox-%03d.png # convert *.jpeg images.pdf # 把所有图片转换成一份简单的 PDF 文档 # gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=all.pdf \ file1.pdf file2.pdf ... # 在 Windows 上使用 '#' 代替 '='
17.4. 视频转换
# mencoder -o videoout.avi -oac mp3lame -ovc lavc -srate 11025 \ -channels 1 -af-adv force=1 -lameopts preset=medium -lavcopts \ vcodec=msmpeg4v2:vbitrate=600 -mc 0 vidoein.AVI
17.5. 拷贝音频光盘
# cdparanoia -B # 拷贝音轨成 wav 文件到当前目录列表(dir) # lame -b 256 in.wav out.mp3 # 编码成 256 kb/s 的 mp3 # for i in *.wav; do lame -b 256 $i `basename $i .wav`.mp3; done # oggenc in.wav -b 256 out.ogg # 编码成 256 kb/s 的 Ogg Vorbis
18. 打印
18.1. 打印命令 lpr
# lpr unixtoolbox.ps # 用默认打印机打印 # export PRINTER=hp4600 # 更改默认打印机 # lpr -Php4500 #2 unixtoolbox.ps # 指定打印机 hp4500 并打印 2 份 # lpr -o Duplex=DuplexNoTumble ... # 启用双面打印 # lpr -o PageSize=A4,Duplex=DuplexNoTumble ... # lpq # 查看默认打印机的队列 # lpq -l -Php4500 # 详细显示打印机队列信息 # lprm - # 删除所有打印机内的用户打印作业 # lprm -Php4500 3186 # 删除作业 3186. 可使用 lpq 查看作业号 # lpc status # 列印所有可用打印机 # lpc status hp4500 # 如果打印机在线, 查看其状态和列队长度 # gs -dSAFER -dNOPAUSE -sDEVICE=deskjet -sOutputFile=\|lpr file.pdf
19. 数据库
19.1. PostgreSQL
19.1.1. 更改 root 用户或其它用户的密码
# psql -d template1 -U pgsql > alter user pgsql with password 'pgsql_password';
19.1.2. 创建用户和数据库
# createuser -U pgsql -P bob # -P 会请求一个秘密 # createdb -U pgsql -O bob bobdb # 新数据库 bobdn 的所有者是 bob # dropdb bobdb # 删除数据库 bobdb # dropuser bob # 删除用户 bob
19.1.3. 允许远程访问
文件 $PGSQL_DATA_D/pg_hba.conf 定义了访问控制. 举例:
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host bobdb bob 212.117.81.42 255.255.255.255 password host all all 0.0.0.0/0 password
19.1.4. 备份和恢复
# pg_dump --clean dbname > dbname_sql.dump # psql dbname < dbname_sql.dump # pg_dumpall --clean > full.dump # psql -f full.dump postgres
19.2. MySQL
19.2.1. 更改 mysql root 用户或其它用户的密码
19.2.2. 创建用户和数据库
# mysql -u root mysql mysql> CREATE DATABASE bobdb; mysql> GRANT ALL ON *.* TO 'bob'@'%' IDENTIFIED BY 'pwd'; mysql> DROP DATABASE bobdb; mysql> DROP USER bob; mysql> DELETE FROM mysql.user WHERE user='bob and host='hostname'; mysql> FLUSH PRIVILEGES;
19.2.3. 允许远程访问
# mysql -u root mysql mysql> GRANT ALL ON bobdb.* TO bob@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'PASSWORD'; mysql> REVOKE GRANT OPTION ON foo.* FROM bar@'xxx.xxx.xxx.xxx'; mysql> FLUSH PRIVILEGES;
19.2.4. 备份和恢复
# mysqldump -u root -psecret --add-drop-database dbname > dbname_sql.dump # mysql -u root -psecret -D dbname < dbname_sql.dump # mysqldump -u root -psecret --add-drop-database --all-databases > full.dump # mysql -u root -psecret < full.dump
19.3. SQLite
19.3.1. 备份和恢复
# sqlite database.db .dump > dump.sql # 备份 # sqlite database.db < dump.sql # 恢复
19.3.2. 转换 2.x 到 3.x 数据库
sqlite database_v2.db .dump | sqlite3 database_v3.db
20. 磁盘限额
20.1. Linux 设置
添加 usrquota 到 fstab 的挂载类型中:
/dev/sda2 /home reiserfs rw,acl,user_xattr,usrquota 1 1
# mount -o remount /home # quotacheck -vum /home # chmod 644 /home/aquota.user # quotaon -vu /home # quota -v
20.2. FreeBSD 设置
添加限额到 fstab 选项(是 userquota, 而不是 usrquota)中:
/dev/ad0s1d /home ufs rw,noatime,userquota 2 2
# mount /home
在 /etc/rc.conf 中启用磁盘限额并开启 quota 服务.
enable_quotas="YES" check_quotas="YES"
# /etc/rc.d/quota start
20.3. 分配限额
# edquota -u colin
20.4. 给许多用户分配限额
# edquota -p refuser `awk -F: $3 > 499 {print $1}' /etc/passwd` # edquota -p refuser user1 user2 # 复用给 2 个用户
20.5. 检查
# quota -u colin # 查看用户的限额 # repquota /home # 所有用户在这个分区上的限额情况
21. SHELLS
过滤器(Filter)非常有用并且可用于管道(pipe):
grep- 模式匹配
sed- 查找并替换字符串或字符
cut- 从一个标记开始打印所指定列数据
sort- 按字母或数字排序
uniq- 删除一个文件中重复行
21.1. bash
# cmd 1> file # 重定向标准输出到 file. # cmd 2> file # 重定向标准错误输出到 file. # cmd 1>> file # 重定向标准输出并追加到 file. # cmd &> file # 重定向标准输出和标准错误输出到 file. # cmd >file 2>&1 # 重定向标准错误输出到标准输出然后重定向到 file. # cmd1 | cmd2 # cmd1 的输出通过管道连接到 cmd2 的输入 # cmd1 2>&1 | cmd2 # cmd1 的输出和错误输出通过管道连接到 cmd2 的输入
/.bashrc:
# in .bashrc bind '"\e[A"':history-search-backward bind '"\e[B"':history-search-forward set -o emacs set bell-style visible PS1="\[\033[1;30m\][\[\033[1;34m\]\u\[\033[1;30m\]" PS1="$PS1@\[\033[0;33m\]\h\[\033[1;30m\]]\[\033[0;37m\]" PS1="$PS1\w\[\033[1;30m\]>\[\033[0m\]" alias ls='ls -aF' alias ll='ls -aFls' alias la='ls -all' alias ..='cd ..' alias ...='cd ../..' export HISTFILESIZE=5000 export CLICOLOR=1 export LSCOLORS=ExGxFxdxCxDxDxBxBxExEx
21.2. tcsh
# cmd >& file # 重定向标准输出和标准错误输出到 file. # cmd >>& file # 追加标准输出和标准错误输出到 file. # cmd1 | cmd2 # cmd1 的输出通过管道连接到 cmd2 的输入 # cmd1 |& cmd2 # cmd1 的输出和错误输出通过管道连接到 cmd2 的输入
/.cshrc:
# in .cshrc alias ls 'ls -aF' alias ll 'ls -aFls' alias la 'ls -all' alias .. 'cd ..' alias ... 'cd ../..' set prompt = "%B%n%b@%B%m%b%/> " set history = 5000 set savehist = ( 6000 merge ) set autolist set visiblebell bindkey -e bindkey -k up history-search-backward bindkey -k down history-search-forward setenv CLICOLOR 1 setenv LSCOLORS ExGxFxdxCxDxDxBxBxExEx
22. 脚本
22.1. 基础
22.1.1. 变量和参数
MESSAGE="Hello World" PI=3.1415 N=8 TWON=`expr $N * 2` TWON=$(($N * 2)) TWOPI=`echo "$PI * 2" | bc -l` ZERO=`echo "c($PI/4)-sqrt(2)/2" | bc -l`
22.1.2. 命令行参数
$0, $1, $2, ...- $0 命令本身
$#- 命令参数个数
$*- 所有参数(也可以是 $@)
22.1.3. 一些特殊的变量
$$- 当前进程 ID
$?- 最后命令退出状态码
- (no term)
`pwd`${mypath##*/}- 只显示文件名
${mypath%%.*}- 除了扩展名的全路径
- (no term)
var2=${var:=string}
22.1.4. 结构控制
for file in `ls` do echo $file done count=0 while [ $count -lt 5 ]; do echo $count sleep 1 count=$(($count + 1)) done myfunction() { find . -type f -name "*.$1" -print } myfunction "txt" MYHOME=/home/colin cat > testhome.sh << _EOF # 所有_EOF前的代码都会进入到 testhome.sh 文件中去 if [ -d "$MYHOME" ] ; then echo $MYHOME exists else echo $MYHOME does not exist fi _EOF sh testhome.sh
22.2. Bourne 脚本实例
#!/bin/sh # 此脚本可以创建一份供双面打印机打印的 PDF 格式的书 if [ $# -ne 1 ]; then # 检查参数是否等于 1 echo 1>&2 "Usage: $0 HtmlFile" exit 1 # 如果不等于1, 非0退出 fi file=$1 # 文件变量 fname=${file%.*} # 文件名变量 fext=${file#*.} # 文件扩展名变量 prince $file -o $fname.pdf # www.princexml.com pdftops -paper A4 -noshrink $fname.pdf $fname.ps # 创建 postscript 小册子 cat $fname.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $fname.book.ps $fname.book.pdf exit 0 # exit 0 意为成功
22.3. 一些 sed 命令
sed 's/string1/string2/g' # 替换 string1 为 string2 sed -i 's/wroong/wrong/g' *.txt # 用 g 替换所有返回的单词 sed 's/\(.*\)1/\12/g' # 修改 anystring1 为 anystring2 sed '/<p>/,/<\/p>/d' t.xhtml # 删除以 <p> 开始, 以 </p> 结尾的行 sed '/ *#/d; /^ *$/d' # 删除注释和空行 sed 's/[ \t]*$//' # 删除行尾空格 (使用 tab 代替 \t) sed 's/^[ \t]*//;s/[ \t]*$//' # 删除行头尾空格 sed 's/[^*]/[&]/' # 括住首字符 [] top -> [t]op sed = file | sed 'N;s/\n/\t/' > file.num # 为文件添加行号
22.4. 正则表达式
[\^$.|?*+()- 特殊字符
\- 转义特殊字符
*- 重复前项 0 次或多次
.- 单个字符除换行符
.*- 匹配 0 个或多个字符
^- 匹配字符串行开始处
$- 匹配字符串行结尾处
.$- 匹配字符串行最后一个字符
^ $- 匹配单个空格的行
[^A-Z]- 匹配任何以 A-Z 字符开始的行
22.5. 一些实用命令
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n # 排序 IPv4 格式的 IP 地址 echo 'Test' | tr '[:lower:]' '[:upper:]' # 转换成大写 echo foo.bar | cut -d . -f 1 # 返回 foo PID=$(ps | grep script.sh | grep bin | awk '{print $1}') PID=$(ps axww | grep [p]ing | awk '{print $1}') IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//') # Linux IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//') # FreeBSD if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi # 文件改变了? cat /etc/master.passwd | grep -v root | grep -v \*: | awk -F":" \ '{ printf("%s:%s\n", $1, $2) }' > /usr/local/etc/apache2/passwd testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \ root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$) :(){ :|:& };: # bash fork 炸弹 tail +2 file > file2 # 删除文件的第一行 # ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh # ls *.c | sed "s/.*/cp & &.$(date "+%Y%m%d")/" | sh # rename .cxx .cpp *.cxx # for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done
23. 编程
23.1. C 基础
strcpy(newstr,str)- 拷贝 str 到 newstr
expr1 ? expr2 : expr3- if (expr1) expr2 else expr3
x = (y > z) ? y : z;- if (y > z) x = y; else x = z;
int a[]={0,1,2};- 初始化数组
int a[2][3]={{1,2,3},{4,5,6}};- 初始化二维数组
sprintf(str, "%d", i);- 从 i 转换成 char str
23.2. C 实例
simple.c:
#include <stdio.h> main() { int number=42; printf("The answer is %i\n", number); }
编译:
# gcc simple.c -o simple # ./simple
23.3. C++ 基础
*pointer- 指向对象的指针
&obj- 对象 obj 的地址
obj.x- 类(对象) obj 成员 x
pobj->x- 指针 pobj 指向类(对象)成员 x
23.4. C++ 实例
23.4.1. IPv4 class
IPv4.h:
#ifndef IPV4_H #define IPV4_H #include <string> namespace GenericUtils { class IPv4 { public: IPv4(); ~IPv4(); std::string IPint_to_IPquad(unsigned long ip); }; } #endif // IPV4_H
IPv4.cpp:
#include "IPv4.h" #include <string> #include <sstream> using namespace std; using namespace GenericUtils; IPv4::IPv4() {} IPv4::~IPv4() {} string IPv4::IPint_to_IPquad(unsigned long ip) { ostringstream ipstr; ipstr << ((ip &0xff000000) >> 24) << "." << ((ip &0x00ff0000) >> 16) << "." << ((ip &0x0000ff00) >> 8) << "." << ((ip &0x000000ff)); return ipstr.str(); }
23.4.2. 程序 simplecpp.cpp
#include "IPv4.h" #include <iostream> #include <string> using namespace std; int main (int argc, char* argv[]) { string ipstr; unsigned long ipint = 1347861486; GenericUtils::IPv4 iputils; ipstr = iputils.IPint_to_IPquad(ipint); cout << ipint << " = " << ipstr << endl; return 0; }
编译和执行:
# g++ -c IPv4.cpp simplecpp.cpp # g++ IPv4.o simplecpp.o -o simplecpp.exe # ./simplecpp.exe # ldd /sbin/ifconfig
23.5. 简单的 Makefile
CC = g++ CFLAGS = -O OBJS = IPv4.o simplecpp.o simplecpp: ${OBJS} ${CC} -o simplecpp ${CFLAGS} ${OBJS} clean: rm -f ${TARGET} ${OBJS}
24. 在线帮助
24.1. 文档
24.2. 其他 Unix/Linux 参考
- Rosetta Stone for Unix (a Unix command translator)
- Unix guide cross reference
- Linux 命令行列表
- Short Linux reference