2008年12月27日星期六

pkg-config

这是为了方便安装一些 libs 用于编译、连接时给 cc or ld 送参数的程序,
/usr/lib/pkgconfig
/usr/share/pkgconfig
/usr/share/aclocal/pkg.m4
/usr/share/man/man1
/usr/share/man/man1/pkg-config.1.gz
/usr/share/doc/pkg-config/README
/usr/share/doc/pkg-config/AUTHORS
/usr/share/doc/pkg-config/copyright
/usr/share/doc/pkg-config/changelog.gz
/usr/share/doc/pkg-config/NEWS.gz
/usr/share/doc/pkg-config/changelog.Debian.gz
/usr/bin/pkg-config
用起来也很简单,就是 --cflags 和 --ldflags 一个给 cc 一个给 ld,如果需要更多的细节看 man pages。pkg-config 的工作原理很简单,就是找对应的 .pc 文件,多数 libs 都提供了这个,方便大家编译、连接的时候使用,搜索的路径为 PKG_CONFIG_PATH 用 : 分割的路径,默认的 LIB/pkcconfig 如 /usr/lib/pkgconfig/ 里面存有多数使用 pkg-config 的库的 pc 文件。另外可以用 PKG_CONFIG_LIBDIR 环境变量覆盖默认的搜索路径。

2008年12月20日星期六

rsync

rsync 是一个强大同步工具,不仅可以通过自己的 daemon 实现客户端和服务器端的同步,还可以通过 shell(走 ssh 或者 rsh)进行同步,还可以把本地两个目录进行同步。嗯,这个包里面有如下内容:
/usr/bin/rsync
/usr/share/doc/rsync/examples
/usr/share/doc/rsync/examples/rsyncd.conf
/usr/share/doc/rsync/examples/logrotate.conf.rsync
/usr/share/doc/rsync/scripts/cull_options.gz
/usr/share/doc/rsync/scripts/atomic-rsync.gz
/usr/share/doc/rsync/scripts/cvs2includes.gz
/usr/share/doc/rsync/scripts/file-attr-restore.gz
/usr/share/doc/rsync/scripts/files-to-excludes.gz
/usr/share/doc/rsync/scripts/git-set-file-times.gz
/usr/share/doc/rsync/scripts/logfilter.gz
/usr/share/doc/rsync/scripts/lsh.gz
/usr/share/doc/rsync/scripts/mnt-excl.gz
/usr/share/doc/rsync/scripts/munge-symlinks.gz
/usr/share/doc/rsync/scripts/rrsync.gz
/usr/share/doc/rsync/scripts/rsyncstats.gz
/usr/share/doc/rsync/changelog.Debian.gz
/usr/share/doc/rsync/README.gz
/usr/share/doc/rsync/tech_report.tex.gz
/usr/share/doc/rsync/TODO.gz
/usr/share/doc/rsync/changelog.gz
/usr/share/doc/rsync/copyright
/usr/share/man/man1/rsync.1.gz
/usr/share/man/man5/rsyncd.conf.5.gz
/etc/default/rsync
/etc/init.d/rsync
可见,主要掌握 rsync 命令,它既是客户端,也是服务器端。我们先看作为一个 client 如果使用 rsync。基本上 rsync 和 scp 这类命令一样,两个地址格式一样,如果使用 shell 方式,如果使服务器则 server::module 的方式。参数常用的有 -a 使用 archive 方式(和 tar 一样),-v 详细显示,-z 压缩传输,--rsh 选择 ssh 或者 rsh(-e,提供连接命令,如需要其他的 options 在这里用引号),-q 取消 motd,-c 使用 checksum(默认使用时间、大小),-r 递归到目录,-R 使用相对路径,-u 仅仅 update 更新的内容,-p 保持属性,-n 测试,-C 排出 CVS 目录,-f 提供 filter 功能... 总而言之 rsync 提供了非常详尽的口之同步使用的选项。要求两边都有 rsync 命令。

建立一个 daemon 使用 --daemon 参数,占用 873 端口,可以用 inetd 来启用该 daemon。

2008年12月6日星期六

pptp-linux

这是 pptp 协议的客户端,可以和 ppp 协同工作。内容很简单,
/usr/sbin/pptp
/usr/sbin/pptpsetup
/usr/share/man/man8/pptp.8.gz
/usr/share/man/man8/pptpsetup.8.gz
/usr/share/doc/pptp-linux/README
/usr/share/doc/pptp-linux/TODO
/usr/share/doc/pptp-linux/USING
/usr/share/doc/pptp-linux/AUTHORS
/usr/share/doc/pptp-linux/DESIGN.CALLMGR
/usr/share/doc/pptp-linux/DESIGN.PPTP
/usr/share/doc/pptp-linux/PORTING
/usr/share/doc/pptp-linux/README.Debian
/usr/share/doc/pptp-linux/copyright
/usr/share/doc/pptp-linux/changelog.Debian.gz
/usr/share/doc/pptp-linux/changelog.gz
/etc/ppp/options.pptp
主要就是 pptp 这个拨号程序啦,pptpsetup 感觉上还不如直接 pon name 直接,兴许是对没有 pon 的 distribution 留的吧。

pptp 其实就是 pptp server-ip 这么简单,参数有 --nolaunchpppd 这是用 pppd 打开 pptp 使用的,当然 pptp 可以单独使用,其他的参数没啥么太多意思。

2008年12月5日星期五

ppp

ppp 是点对点传输协议的 daemon,原来主要是作为拨号的程序,随着现在新的宽带的出现,比如 pptp、l2tp 等 VPN,还有 pppoe 这种技术的出现,它担当了一个维护连接、提供给用户一个一致的使用环境的角色。这里简单介绍一下如何使用 ppp 建立一些常用的连接。

这是该包的描述:
$ dpkg -s ppp
Package: ppp
Status: install ok installed
Priority: optional
Section: admin
Installed-Size: 892
Maintainer: Marco d'Itri
Architecture: i386
Version: 2.4.4rel-10
Replaces: ppp-pam, ppp-udeb
Depends: libc6 (>= 2.7-1), libpam-modules, libpam-runtime (>= 0.76-13.1), libpam0g (>= 0.99.7.1), libpcap0.8 (>= 0.9.3-1), netbase, procps
Suggests: iptables
Conflicts: makedev (<<>
含有如下的内容,
/etc/bash_completion.d/pon
/etc/apm/event.d/ppp
/etc/ppp/peers
/etc/ppp/ip-up.d/0000usepeerdns
/etc/ppp/ip-down.d/0000usepeerdns
/etc/ppp/ipv6-up.d
/etc/ppp/ipv6-down.d
/etc/ppp/options
/etc/ppp/ip-up
/etc/ppp/ip-down
/etc/ppp/ipv6-up
/etc/ppp/ipv6-down
/etc/chatscripts
/etc/chatscripts/pap
/etc/logrotate.d/ppp
/etc/init.d/pppd-dns
/etc/pam.d/ppp
/usr/share/ppp/pap-secrets
/usr/share/ppp/chap-secrets
/usr/share/ppp/provider.peer
/usr/share/ppp/provider.chatscript
/usr/share/man/man8/chat.8.gz
/usr/share/man/man8/pppd-radius.8.gz
/usr/share/man/man8/pppd-radattr.8.gz
/usr/share/man/man8/pppd.8.gz
/usr/share/man/man8/pppstats.8.gz
/usr/share/man/man8/pppdump.8.gz
/usr/share/man/man8/pppoe-discovery.8.gz
/usr/share/man/man1/pon.1.gz
/usr/share/doc/ppp/README.MPPE
/usr/share/doc/ppp/README.MSCHAP81
/usr/share/doc/ppp/README.cbcp
/usr/share/doc/ppp/README.pppoe
/usr/share/doc/ppp/README.pwfd
/usr/share/doc/ppp/README.STATIC-IP
/usr/share/doc/ppp/README.win9x
/usr/share/doc/ppp/defaultroute
/usr/share/doc/ppp/copyright
/usr/share/doc/ppp/examples/scripts/chatchat/chatchat.c.gz
/usr/share/doc/ppp/examples/scripts/chatchat/README.gz
/usr/share/doc/ppp/examples/scripts/chat-callback
/usr/share/doc/ppp/examples/scripts/callback
/usr/share/doc/ppp/examples/scripts/pon.1
/usr/share/doc/ppp/examples/scripts/plog
/usr/share/doc/ppp/examples/scripts/ip-down.local.add
/usr/share/doc/ppp/examples/scripts/ip-up.local.add
/usr/share/doc/ppp/examples/scripts/ipv6-down.sample
/usr/share/doc/ppp/examples/scripts/ipv6-up.sample
/usr/share/doc/ppp/examples/scripts/options-rsh-loc
/usr/share/doc/ppp/examples/scripts/options-rsh-rem
/usr/share/doc/ppp/examples/scripts/options-ssh-loc
/usr/share/doc/ppp/examples/scripts/options-ssh-rem
/usr/share/doc/ppp/examples/scripts/poff
/usr/share/doc/ppp/examples/scripts/pon
/usr/share/doc/ppp/examples/scripts/ppp-on-dialer
/usr/share/doc/ppp/examples/scripts/ppp-off
/usr/share/doc/ppp/examples/scripts/ppp-on
/usr/share/doc/ppp/examples/scripts/ppp-on-rsh
/usr/share/doc/ppp/examples/scripts/ppp-on-ssh
/usr/share/doc/ppp/examples/scripts/redialer
/usr/share/doc/ppp/examples/scripts/secure-card
/usr/share/doc/ppp/examples/scripts/README.gz
/usr/share/doc/ppp/examples/scripts/autopppd.gz
/usr/share/doc/ppp/examples/userscripts-down
/usr/share/doc/ppp/examples/userscripts-up
/usr/share/doc/ppp/examples/popp
/usr/share/doc/ppp/examples/filters
/usr/share/doc/ppp/examples/options.ttyXX
/usr/share/doc/ppp/examples/peers-pppoa
/usr/share/doc/ppp/examples/peers-pppoe
/usr/share/doc/ppp/examples/interfaces
/usr/share/doc/ppp/examples/per-linkname
/usr/share/doc/ppp/changelog.Debian.gz
/usr/share/doc/ppp/NEWS.Debian.gz
/usr/share/doc/ppp/changelog.gz
/usr/share/doc/ppp/FAQ.gz
/usr/share/doc/ppp/README.gz
/usr/share/doc/ppp/SETUP.gz
/usr/share/doc/ppp/PLUGINS.gz
/usr/share/doc/ppp/README.MSCHAP80.gz
/usr/share/doc/ppp/README.Debian.gz
/usr/bin/pon
/usr/bin/plog
/usr/bin/poff
/usr/sbin
/usr/sbin/chat
/usr/sbin/pppoe-discovery
/usr/sbin/pppd
/usr/sbin/pppstats
/usr/sbin/pppdump
/usr/lib/pppd/2.4.4/minconn.so
/usr/lib/pppd/2.4.4/passprompt.so
/usr/lib/pppd/2.4.4/passwordfd.so
/usr/lib/pppd/2.4.4/winbind.so
/usr/lib/pppd/2.4.4/rp-pppoe.so
/usr/lib/pppd/2.4.4/pppoatm.so
/usr/lib/pppd/2.4.4/radius.so
/usr/lib/pppd/2.4.4/radattr.so
/usr/lib/pppd/2.4.4/radrealms.so
/usr/share/man/man1/poff.1.gz
/usr/share/man/man1/plog.1.gz
这是一个比较复杂的包,我们一点一点来看。

首先有个目录 /etc/bash_completion.d,这里面是 bash completion 的巢(后面介绍吧),激活 bash completion 只需要运行 /etc/bash_completion(用 source 在当前 shell 里面执行),该包的作用是为 pon/poff 增加补全功能(bash 自己有对目录、文件、变量名的补全)。这个补全是针对一个特定的 peer。

另外一个目录 /etc/apm/event.d 是高级电源管理(advanced power management)的目录,这是当 apmd 决定 suspend/resume 时调用的 ppp 的命令。

/etc/logrotate.d 是 ppp 日志回卷的操作,这是给 logrotate 程序用来操作 ppp 日志的配置。

/etc/inin.d 里面是 ppp 用来解决 /etc/resolv.conf 问题的脚本,原来该文件是手工编辑的,那么当 ppp 连接由于系统崩溃断掉,原来的文件会被 ppp 连接产生的所覆盖。这个脚本会检查这种情况并恢复原来的版本。现在的 DNS 解析似乎是靠另外的东西维护的了,因此觉得是不是可以不要了?

/etc/pam.d 里面是关于使用 ppp 连接进行 login 的 PAM 配置。

/etc/ppp 里面是 pppd 本身的配置,这里面重要的东西有 ip-up 和 ip-down,这里面是 pppd 运行起来后需要调用 ip-up 设置某些东西,断开连接后调用 ip-down 恢复某些东西,它们分别有 ip-up.d 和 ip-down.d 目录用于配置一些细化的项目,如 DNS,如果装过 firestarter 还在这里配置防火墙这些东西。另外 /etc/chatscripts 里面是各种连接会话的过程。

/etc/chatscripts 里面是用于 chat 程序拨号(modem)使用的脚本。

一个标准的 ppp 拨号的配置包含在 peers 里面建立 ppp 拨号脚本,如调用拨号程序,设置一些专有参数,并且调用 /etc/ppp/options 里面公用的参数部分。然后在 /etc/ppp/pap-secrets 或者 /etc/ppp/chap-secrets 里面配置用户、密码等。之后通过 pon 打开这个连接,plog 查看日志,poff 挂断。

先看看几个简单的命令,pppstats 显示 ppp 连接的统计信息,pppdump 是把 ppp record file 转换成为可读的格式。pppoe-discovery 用于发现 ethernet 里面 pppoe 的 AP。

然后就是核心程序 pppd 了,这里依照 man page 里面列出一些常用的选项。ttyname 使用的设备名(和串行连接一样,pppd 会占用一个 pty);speed 连接速率(就是 baud rate);auth/noauth,需要验证才允许连接;call name 是调用 /etc/ppp/peers/name;connect script 是拨号脚本;(no)defaultroute 是将连接上的 peer 作为 default route 加入 route table;replacedefaultroute,这是替换;disconnect 用于断掉连接调用;escape 设置逃脱键;file 从另一个文件读入信息;init 一般是调用拨号(chat)作一些准备工作;lock 为工作的设备设置一个 exclusive 访问的锁;mtu 和 mru 意思很明确。

另外一些选项有 (no)bsdcomp 打开 BSD 压缩;debug 打开调试功能;holdoff 断线等待时间;maxfail 指定最大重连次数,0 为 infinity;idle 闲置切断连接时间;ipparam 为 ip-up/down 提供参数;ipx,打开 ipx 协议;logfile 指定 log file;mppe-stateful 是加密 MPPE 的一种;refuse-* 不使用某认证方式。

下面是几个配置的例子,如教育网直通车,可以在 /etc/ppp/peers 里面加一个 eduexp 内容如下:
pty "pptp 58.207.255.82 --nolaunchpppd"
name fudan_iipl
remotename eduexp
file /etc/ppp/options.pptp.vipedu
ipparam eduexp
这里主要设置了拨号方式,并且设置的 name 方便在 /etc/ppp/chap-secrets 里面获得对应的密码。这里读入的文件 options.pptp.vipedu 是关于其他的参数的配置(常把公用的放在这里),如下
lock
noauth
refuse-eap
refuse-chap
refuse-mschap
nobsdcomp
nodeflate
persist
defaultroute
maxfail 0
holdoff 120
可见配置一个拨号服务是非常容易的。

iptables

这块内容和网络极为相关,建议多看看这方面的东西,比如这里给出的一些相关文档。iptables 简单的理解起来就是 Linux 下的网络防火墙,但实际上它提供给我们更多其他的东西,比如 ip 伪装、端口映射等等。此物对网络管理之重要,就如同球队的灵魂人物。

我们看下这个包的介绍,
$ dpkg -s iptables
Package: iptables
Status: install ok installed
Priority: important
Section: net
Installed-Size: 1336
Maintainer: Laurence J. Lane
Architecture: i386
Version: 1.4.1.1-4
Depends: libc6 (>= 2.7-1)
Description: administration tools for packet filtering and NAT
These are the user-space administration tools for the Linux
kernel's netfilter and iptables. netfilter and iptables provide
a framework for stateful and stateless packet filtering, network
and port address translation, and other IP packet manipulation.
The framework is the successor to ipchains.
.
netfilter and iptables are used in applications such as Internet
connection sharing, firewalls, IP accounting, transparent proxying,
advanced routing and traffic control.
Homepage: http://www.netfilter.org/
该包里面程序不多,
/sbin/ip6tables
/sbin/ip6tables-multi
/sbin/ip6tables-restore
/sbin/ip6tables-save
/sbin/iptables
/sbin/iptables-multi
/sbin/iptables-restore
/sbin/iptables-save
/usr/sbin/iptables-xml
/usr/sbin/iptables-apply
/usr/share/man/man8/iptables.8.gz
/usr/share/man/man8/iptables-restore.8.gz
/usr/share/man/man8/iptables-save.8.gz
/usr/share/man/man8/iptables-xml.8.gz
/usr/share/man/man8/ip6tables.8.gz
/usr/share/man/man8/ip6tables-restore.8.gz
/usr/share/man/man8/ip6tables-save.8.gz
/usr/share/man/man8/iptables-apply.8.gz
/usr/share/doc/iptables/README.Debian
/usr/share/doc/iptables/copyright
/usr/share/doc/iptables/changelog.Debian.gz
/usr/share/doc/iptables/changelog.gz
/lib/xtables/libxt_CLASSIFY.so
/lib/xtables/libxt_CONNMARK.so
/lib/xtables/libxt_CONNSECMARK.so
/lib/xtables/libxt_DSCP.so
/lib/xtables/libxt_MARK.so
/lib/xtables/libxt_NFLOG.so
/lib/xtables/libxt_NFQUEUE.so
/lib/xtables/libxt_NOTRACK.so
/lib/xtables/libxt_RATEEST.so
/lib/xtables/libxt_SECMARK.so
/lib/xtables/libxt_TCPMSS.so
/lib/xtables/libxt_TCPOPTSTRIP.so
/lib/xtables/libxt_TOS.so
/lib/xtables/libxt_TRACE.so
/lib/xtables/libxt_comment.so
/lib/xtables/libxt_connbytes.so
/lib/xtables/libxt_connlimit.so
/lib/xtables/libxt_connmark.so
/lib/xtables/libxt_conntrack.so
/lib/xtables/libxt_dccp.so
/lib/xtables/libxt_dscp.so
/lib/xtables/libxt_esp.so
/lib/xtables/libxt_hashlimit.so
/lib/xtables/libxt_helper.so
/lib/xtables/libxt_iprange.so
/lib/xtables/libxt_length.so
/lib/xtables/libxt_limit.so
/lib/xtables/libxt_mac.so
/lib/xtables/libxt_mark.so
/lib/xtables/libxt_multiport.so
/lib/xtables/libxt_owner.so
/lib/xtables/libxt_physdev.so
/lib/xtables/libxt_pkttype.so
/lib/xtables/libxt_quota.so
/lib/xtables/libxt_rateest.so
/lib/xtables/libxt_sctp.so
/lib/xtables/libxt_standard.so
/lib/xtables/libxt_state.so
/lib/xtables/libxt_statistic.so
/lib/xtables/libxt_string.so
/lib/xtables/libxt_tcp.so
/lib/xtables/libxt_tcpmss.so
/lib/xtables/libxt_time.so
/lib/xtables/libxt_tos.so
/lib/xtables/libxt_u32.so
/lib/xtables/libxt_udp.so
/lib/xtables/libipt_CLUSTERIP.so
/lib/xtables/libipt_DNAT.so
/lib/xtables/libipt_ECN.so
/lib/xtables/libipt_LOG.so
/lib/xtables/libipt_MASQUERADE.so
/lib/xtables/libipt_MIRROR.so
/lib/xtables/libipt_NETMAP.so
/lib/xtables/libipt_REDIRECT.so
/lib/xtables/libipt_REJECT.so
/lib/xtables/libipt_SAME.so
/lib/xtables/libipt_SET.so
/lib/xtables/libipt_SNAT.so
/lib/xtables/libipt_TTL.so
/lib/xtables/libipt_ULOG.so
/lib/xtables/libipt_addrtype.so
/lib/xtables/libipt_ah.so
/lib/xtables/libipt_ecn.so
/lib/xtables/libipt_icmp.so
/lib/xtables/libipt_policy.so
/lib/xtables/libipt_realm.so
/lib/xtables/libipt_recent.so
/lib/xtables/libipt_set.so
/lib/xtables/libipt_ttl.so
/lib/xtables/libipt_unclean.so
/lib/xtables/libip6t_HL.so
/lib/xtables/libip6t_LOG.so
/lib/xtables/libip6t_REJECT.so
/lib/xtables/libip6t_ah.so
/lib/xtables/libip6t_dst.so
/lib/xtables/libip6t_eui64.so
/lib/xtables/libip6t_frag.so
/lib/xtables/libip6t_hbh.so
/lib/xtables/libip6t_hl.so
/lib/xtables/libip6t_icmp6.so
/lib/xtables/libip6t_ipv6header.so
/lib/xtables/libip6t_mh.so
/lib/xtables/libip6t_policy.so
/lib/xtables/libip6t_rt.so
首先要理解 iptables 工作是在 IP 这层上(一般 TCP/IP 分四层结构,最下面是物理层,然后是 IP,然后是 TCP 层,然后是应用层,物理层管直接通讯,IP 层决定路由,TCP 层决定通讯方式如如何建立连接、出现某些问题是否重发,应用层关心数据传输格式),因此本质上就是处理 IP 数据包,决定不同的包如何处理。和路由表本身实际上是一个层次上的东西,而它工作方式就是在路由不同阶段设置 hook(默认的 chain 就是固定的 5 阶段),而另外依照处理的功能分类,设置了 4 种类型的 table,每一个 rule 依照功能放在对应的 table 里面,在不同的 chain 发挥作用,影响路由过程。

那么 4 个 tables 分别是什么呢?filter,就是一个纯粹的过滤器,这个表格设计的目的就是把不符合规则的包扔掉,比如出现某个设备里面不应该出现的目的地址(完全不修改 packet);nat 是在一个 packet 产生一个新连接的时候查询的 table(可以用来实现 SNAT 和 DNAT,其中 masquerading 是 SNAT 的一种而 port forwarding 和 transparent proxy 是 DNAT 的特例;不管是 SNAT 还是 DNAT 都仅仅修改 ip packet 的头);mangle 是为了修正某些 packet 时候使用(修改了每个 packet 数据本身,以适应不同的网络需要);raw 是...(connection tracking)不懂。前面三个先搞清楚好了。

那么有哪些默认的 chain 呢?在 packet 被应用 route table 之前,有一个 PREROUTING,如果被确定为某设备接受,那么就到达 INPUT,处理完后发出去就是 OUTPUT。如果没有被当前设备接受,一般是 forward 到下一个设备,因此达到 FORWARD,并且之后和经过 OUTPUT 的数据都最后通过 POSTROUTING。用户定义的 chain 和这 5 个默认的 chain 的最大不同是他们只能作为 target 供跳转,而且没有对应的 policy。默认这 5 个 chain 的 policy 决定这个 packet 最后的命运,如果经过一个 chain 中途没有被 DROP 或者怎么就可以继续走到这个 chain 的 policy。

那么首先掌握一些关于 chain 的操作方式,如 -A 给 chain 添加 rule,-D 删除 rule,-I 插入 rule,-R 替换 rule,-L 列出所有的 rule,-S 列出所有 rule 的细节,-F 清除所有 rule,-Z 清零计数器,-N 创建自定义 chain,-X 删除自定义 chain,-P 设定 chain 的 policy,-E 给自定义 chain 重命名。

每一条 rule 本身就是进行某种匹配,如 -p 匹配协议,-s 匹配源地址,-d 匹配目标地址,-i 是输入设备,-o 是输出设备,然后通过 -g (跳转到父 chain)或者 -j(跳转到 target 或者子 chain)。但是 iptables 不仅局限于此,它可以利用 extention 扩展自己的能力,这些 extention 就是上面文件列表中 /lib/xtables 里面的 so 文件了。通常这里可以用 ! 表示匹配的非。

那么如何调用这些 extention 呢?一方面 -p 可以调用某些协议的 extention,也可以用 -m 直接调用某个 extention,下面是常见的一些 extention:
  • addrtype 测试 packet 的地址类型(单播地址,多播地址,广播...)
  • ah 是 IPsec 的 SIP 认证。
  • comment 对某个 rule 添加 comment
  • connbytes 主要应用于把长时间的下载确定出来,加以 shcedule 以便 traffic control
  • connlimit 限制连接数,如多于某个值就 DROP/REJECT。
  • connmark 匹配 netfilter 的 mark,这个可以用 CONNMARK(下面的 target 里面的)标注。
  • conntrak,不懂。
  • dccp,协议?
  • dscp,是 ip packet 里面的一个 field。
  • ecn,是 ip packet 里面 ECN field 和 TCP header。
  • esp,匹配 IPSec 里面 ESP。
  • hashlimit,控制流量使用,和 limit 类似,但是使用 hash 要快点。
  • helper,测试是不是 conntrak 的 helper。
  • icmp,ICMP 协议。
  • iprange,测试地址范围。
  • length,layer 3 payload 大小。
  • limit,有 --limit rate/s 表示大小,--limit-burst 表示开始匹配的相对大小。
  • mac,匹配 MAC 地址。
  • mark,匹配 MARK 这个 target (见下)设置的 packet。
  • multiport,匹配多个端口(15)或者端口范围(算两个),需和 tcp 一起用。
  • owner,连接对应的 socket 的用户信息。
  • physdev,bridge port,继续不懂。
  • pkttype,link layer type,如单播、多播和广播。
  • policy,对应 IPSec 的种类。
  • quota,设定网络的 quota。
  • realm,匹配类似 BGP 这种路由协议的 realm。
  • recent,维护一个 recent 列表,可以用于创建 blacklist。
  • sctp,协议 SCTP。
  • set,匹配被 ipset 定义的 ip
  • state,和 conntrak 的 state 匹配。
  • statistic,匹配某些统计信息。
  • string,匹配字符串。
  • tcp,可以细化到端口、tcp flags(--tcp-flags mask comp)
  • tcpmss,匹配 maximum segment size。
  • time,匹配 packet 到达时间(超时的去掉)
  • tos,匹配 type of service
  • ttl,匹配 time to live field
  • u32,定义一个运算是否 match
  • udp,UDP 协议
  • unclean,不正常的 packet。

那么我们可选的 target 有些什么呢?默认有 ACCEPT 和 DROP,通过 extension,我们还有下面的一些 target 可供选择:
  • CLASSIFY,允许设置 skb->priority,这就是前面 tc 命令中可以利用的一个东西。
  • CLUSTERIP,配置一个 cluster of nodes 共享一个 MAC 和 IP,并均衡这些 nodes 的负载,不懂。
  • CONMARK,如前。
  • CONNSECMARK,继续不懂。
  • DNAT,设置 dst 的 ip 和 port(可以随机)。
  • DSCP,设置 DSCP。
  • ECN,设置 ECN。
  • LOG,打开日志。
  • MARK,见前面。
  • MASQUERADE,只能用于 nat 的 POSTROUTING,修改 src ip。
  • MIRROR,将 src 和 dst 倒换,不知道干啥用。
  • NETMAP,将一个网络进行映射。
  • NFLOG,记录匹配的 packet。
  • NFQUEUE 和 QUEUE 类似。
  • NOTRACK,用于 raw 不懂。
  • RATETEST,测试 rate,用于 ratetest。
  • REDIRECT,将目的地址换成本地 127.0.0.1,似乎是为了 transparent proxy。
  • REJECT,因为 DROP 比较不友好,这个发些 ICMP 回去。
  • SAME,不懂,据说和 DNAT、SNAT 类似 -,-b
  • SECMARK,是 SELinux 用的...
  • SET,跟 set 对应。
  • SNAT,修改 src ip。
  • TCPMSS,修改整个包使得大小合适于对应的网络的 MTU。
  • TCPOPTSTRIP,切掉 TCP 包部分。
  • TOS,设置 type of service。
  • TRACE,要求 kernel log... 不懂。
  • TTL,修改 TTL。
  • ULOG,user space log。

下面我们结合几个具体的应用来分析对应的 iptables 设置。建立一个 VPN 后我们需要打开 ip forward 功能,这一般需要更改 /proc/sys/net/ipv4/ip_forward 里面值为 1,然后
iptables -P FORWARD ACCEPT
把 filter 的 FORWARD 的 polcy 改为 ACCEPT。之后进行 SNAT 伪装 VPN 子网的 packet 即可,如
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
将 nat 表中 POSTROUTING 从 tun0 设备出来的 packet 的源地址伪装。另外一个方面,如果希望把 VPN 中某个主机的端口暴露出来,可以用 DNAT 将其映射:
iptables -t nat -A PREROUTING -p tcp -d 本地另一个地址 -dport 映射端口 -j DNAT --to VPN主机地址:端口

最后我们看看这个包里面其他的应用程序的作用。iptables-restore 从 stdin 读入数据恢复原来的 iptables 配置,iptables-save 则可以选择导出 ptables 配置到 stdout。iptables-xml 将 iptables 配置导出为 xml 格式。iptables-apply 是一种安全的远程应用 iptables 配置的程序,如果使用后用户无法 confirm 会自动回滚到原来的配置。

2008年11月30日星期日

iproute (上)

嗯看看说明
$ dpkg -s iproute
Package: iproute
Status: install ok installed
Priority: important
Section: net
Installed-Size: 920
Maintainer: Debian iproute maintainers
Architecture: i386
Version: 20080725-2
Provides: arpd
Depends: libc6 (>= 2.7-1), libdb4.6
Recommends: libatm1
Suggests: iproute-doc
Conflicts: arpd
Conffiles:
/etc/iproute2/rt_dsfield da0ef3e6e9880e6ee4d64782cb4a5fcf
/etc/iproute2/ematch_map 0b9befbbbee4b415319b8070f18b9b88
/etc/iproute2/rt_scopes 6298b8df09e9bda23ea7da49021ca457
/etc/iproute2/rt_protos 83da07a831e71eb4f6dfaec3d27de345
/etc/iproute2/rt_tables a1313318d6778fe6b8c680248ef5a463
/etc/iproute2/rt_realms 7137bdf40e8d58c87ac7e3bba503767f
Description: networking and traffic control tools
The iproute suite, also known as iproute2, is a collection of
utilities for networking and traffic control.
.
These tools communicate with the Linux kernel via the (rt)netlink
interface, providing advanced features not available through the
legacy net-tools commands 'ifconfig' and 'route'.
Homepage: http://www.linux-foundation.org/en/Net:Iproute2
可见我老土多年,还在 ifconfig 和 route 中,趁早学习下新思维 -,-b 这个包里面有
/usr/lib/tc/experimental.dist
/usr/lib/tc/normal.dist
/usr/lib/tc/paretonormal.dist
/usr/lib/tc/pareto.dist
/usr/lib/tc/q_atm.so
/usr/bin/routef
/usr/bin/routel
/usr/bin/nstat
/usr/bin/lnstat
/usr/share/man/man3/libnetlink.3.gz
/usr/share/man/man8/tc.8.gz
/usr/share/man/man8/tc-cbq-details.8.gz
/usr/share/man/man8/tc-sfq.8.gz
/usr/share/man/man8/routel.8.gz
/usr/share/man/man8/ss.8.gz
/usr/share/man/man8/rtmon.8.gz
/usr/share/man/man8/tc-red.8.gz
/usr/share/man/man8/arpd.8.gz
/usr/share/man/man8/tc-htb.8.gz
/usr/share/man/man8/tc-tbf.8.gz
/usr/share/man/man8/lnstat.8.gz
/usr/share/man/man8/ip.8.gz
/usr/share/man/man8/tc-cbq.8.gz
/usr/share/man/man8/tc-bfifo.8.gz
/usr/share/man/man8/tc-pfifo.8.gz
/usr/share/man/man8/tc-prio.8.gz
/usr/share/man/man8/tc-pfifo_fast.8.gz
/usr/share/man/man8/rtacct.8.gz
/usr/share/doc/iproute/README.Debian
/usr/share/doc/iproute/copyright
/usr/share/doc/iproute/changelog.Debian.gz
/usr/sbin/arpd
/bin/ip
/etc/iproute2/rt_dsfield
/etc/iproute2/ematch_map
/etc/iproute2/rt_scopes
/etc/iproute2/rt_protos
/etc/iproute2/rt_tables
/etc/iproute2/rt_realms
/sbin/rtacct
/sbin/rtmon
/sbin/ss
/sbin/tc
/usr/bin/rtstat
/usr/bin/ctstat
/usr/share/man/man8/ctstat.8.gz
/usr/share/man/man8/routef.8.gz
/usr/share/man/man8/nstat.8.gz
/usr/share/man/man8/rtstat.8.gz
/sbin/ip
命令很多,一个一个来。首先是 routef 和 routel,一个 flush route table,一个列出路由表,更基本的命令是 iproute2,这个后面看。和 route 列出来的有什么不一样呢?
$ routel
target gateway source proto scope dev tbl
10.20.2.65 10.20.2.1 ath0
10.20.2.0/ 24 10.20.2.115 kernel link ath0
default 10.20.2.1 ath0
127.255.255.255 broadcast 127.0.0.1 kernel link lo local
10.20.2.255 broadcast 10.20.2.115 kernel link ath0 local
10.20.2.0 broadcast 10.20.2.115 kernel link ath0 local
10.20.2.115 local 10.20.2.115 kernel host eth0 local
10.20.2.115 local 10.20.2.115 kernel host ath0 local
127.0.0.0 broadcast 127.0.0.1 kernel link lo local
127.0.0.1 local 127.0.0.1 kernel host lo local
127.0.0.0/ 8 local 127.0.0.1 kernel host lo local
default unreachable none lo unspec
::1 :: none lo local
default unreachable none lo unspec
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.20.2.65 10.20.2.1 255.255.255.255 UGH 0 0 0 ath0
10.20.2.0 0.0.0.0 255.255.255.0 U 0 0 0 ath0
0.0.0.0 10.20.2.1 0.0.0.0 UG 0 0 0 ath0
嗯,可见 routel 把一些没有使用的设备对应的 route 也列出来了,看起来好懂点。routef 清理所有的路由信息,这真是好用啊,最讨厌一条一条的删掉了 -,-b

nstat 和 rtacct 是网络统计信息,如
$ nstat
#kernel
IpInReceives 80601 0.0
IpInHdrErrors 2 0.0
IpInAddrErrors 154 0.0
IpInDelivers 80444 0.0
IpOutRequests 53006 0.0
IpOutNoRoutes 163 0.0
IpFragOKs 65 0.0
IpFragCreates 136 0.0
IcmpInErrors 137 0.0
IcmpInTimeExcds 31 0.0
IcmpInParmProbs 87 0.0
IcmpInEchos 15 0.0
IcmpInEchoReps 1 0.0
IcmpInTimestamps 3 0.0
IcmpOutErrors 89 0.0
IcmpOutTimeExcds 86 0.0
IcmpOutEchoReps 3 0.0
IcmpMsgInType0 3 0.0
IcmpMsgInType3 31 0.0
IcmpMsgInType5 15 0.0
IcmpMsgInType8 1 0.0
IcmpMsgInType11 87 0.0
IcmpMsgOutType3 86 0.0
IcmpMsgOutType8 3 0.0
TcpActiveOpens 423 0.0
TcpPassiveOpens 8 0.0
TcpAttemptFails 14 0.0
TcpEstabResets 25 0.0
TcpInSegs 62239 0.0
TcpOutSegs 50769 0.0
TcpRetransSegs 448 0.0
TcpOutRsts 269 0.0
UdpInDatagrams 1513 0.0
UdpNoPorts 80 0.0
UdpOutDatagrams 1802 0.0
Ip6InReceives 18 0.0
Ip6InDelivers 18 0.0
Ip6OutRequests 24 0.0
Ip6OutNoRoutes 1 0.0
Ip6InMcastPkts 18 0.0
Ip6OutMcastPkts 28 0.0
Icmp6InMsgs 1 0.0
Icmp6OutMsgs 7 0.0
Icmp6InRouterAdvertisements 1 0.0
Icmp6OutRouterSolicits 1 0.0
Icmp6OutNeighborSolicits 2 0.0
Icmp6OutMLDv2Reports 4 0.0
Icmp6InType134 1 0.0
Icmp6OutType133 1 0.0
Icmp6OutType135 2 0.0
Icmp6OutType143 4 0.0
Udp6InDatagrams 17 0.0
Udp6OutDatagrams 17 0.0
TcpExtPruneCalled 6 0.0
TcpExtTW 67 0.0
TcpExtDelayedACKs 428 0.0
TcpExtDelayedACKLost 859 0.0
TcpExtTCPPrequeued 5 0.0
TcpExtTCPDirectCopyFromPrequeue 8 0.0
TcpExtTCPHPHits 54267 0.0
TcpExtTCPPureAcks 1930 0.0
TcpExtTCPHPAcks 1202 0.0
TcpExtTCPSackRecovery 2 0.0
TcpExtTCPLossUndo 33 0.0
TcpExtTCPLoss 2 0.0
TcpExtTCPRenoFailures 1 0.0
TcpExtTCPSackFailures 12 0.0
TcpExtTCPLossFailures 6 0.0
TcpExtTCPFastRetrans 2 0.0
TcpExtTCPSlowStartRetrans 43 0.0
TcpExtTCPTimeouts 212 0.0
TcpExtTCPRcvCollapsed 209 0.0
TcpExtTCPDSACKOldSent 799 0.0
TcpExtTCPDSACKOfoSent 12 0.0
TcpExtTCPDSACKRecv 4 0.0
TcpExtTCPAbortOnData 23 0.0
TcpExtTCPAbortOnClose 4 0.0
TcpExtTCPAbortOnTimeout 24 0.0
TcpExtTCPDSACKIgnoredOld 2 0.0
TcpExtTCPDSACKIgnoredNoUndo 2 0.0
IpExtInMcastPkts 164 0.0
IpExtOutMcastPkts 92 0.0
IpExtInBcastPkts 16499 0.0
我们可以看到很多 TCP/IP、ICMP、UDP 等统计信息,类似还有 lnstat(rtstat、ctstat),似乎就是依据不同协议列的统计信息?来源于 /proc/net/stat/。

arpd 是一个 user-space 的 arp daemon,用户可以通过控制它取代 kernel 的 ARP daemon。不知道对像 ARP 攻击的机器是不是可以免疫...

rtmon 是一个监视程序,通过指定一个 log 文件以及监听的内容,并可以用后面 ip 命令显示。命令就是 rtmon file path-to-ur-file list,这个 list 包括 link(eth0...)、address(设备地址) 和 route(路由表)。

ss 是一个 socket 的统计程序,嗯,不过似乎只有 TCP 连接?-a 显示所有的,嗯对发现监听的程序比较有用。

tc 是个很牛的东西,赞... 就是用于控制网络流量(Traffic control)的程序,分四种:shaping(输出流量控制)、scheduling(似乎是为了保证网络通信的带宽,每次传送足够多的数据)、policing(输入流量控制)、dropping(超过流量丢包)。操纵这些需要用三种 objects,qdisc(队列)、classes(每个 qdiscs 含有若干 classes,而每个 class 含有 qdiscs,kernel 根据 class 从 qdisc 里面 dequeue packet),filter(kernel 决定放入哪个 class)。qdisc 有两种,一种是 classless(因此不含有 class?),一种是 classful,当 packet 进入 classful qdisc 就会用 filter 分类(TC、服务类型或者 skb->priority)。对每个 object 使用 id(handler)来命名,tc 提供修改的接口。

另一个核心命令就是 ip 了,基本语法如下
ip [ OPTIONS ] OBJECT { COMMAND | help }
这里可操纵的对象有 link(如 eth0)、addr(如 ipv4 地址)、addrlabel(给地址加的 label)、route(路由表)、rule(路由规则)、neigh(就是 ARP)、tunnel(tunnel over IP,那个什么 ipv6 over v4 是不是?)、maddr(多播地址)、mroute(多播路由)、monitor()、xfrm(IPSec 的 framework)。觉得这块比 ifconfig/route 复杂太多了,准备看完以下文档后再来讨论。

参考文档:Linux Advanced Routing and Traffic Control Howto

usbutils

类似的
/usr/sbin/lsusb
/usr/sbin/update-usbids
/usr/share
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/lsusb.8.gz
/usr/share/man/man8/update-usbids.8.gz
/usr/share/man/man1
/usr/share/doc
/usr/share/doc/usbutils
/usr/share/doc/usbutils/README.Debian
/usr/share/doc/usbutils/copyright
/usr/share/doc/usbutils/changelog.Debian.gz
/usr/share/doc/usbutils/changelog.gz
/usr/share/misc
/usr/bin
/var
/var/lib
/var/lib/usbutils
/var/lib/usbutils/usb.ids
/usr/share/man/man1/lsusb.1.gz
/usr/share/misc/usb.ids
/usr/bin/lsusb
就一个命令,为啥放了两个地方 -,-b 其实 bin 里面的是符号链接。

个么 lsusb 主要就是直接 lsusb(不够 -v),重要的功能就是看看对应 usb 设备的芯片、厂商,比如找摄像头的驱动什么的。里面还会列出来设备使用的电流,比如我的摄像头是 160mA,u 盘是 100mA,另外还有供电方式,如 self powered 和 bus powered,就是不清楚什么区别...

pciutils

主要含有以下内容
/usr/share/misc/pci.ids
/usr/share/man/man8/lspci.8.gz
/usr/share/man/man8/setpci.8.gz
/usr/share/man/man8/update-pciids.8.gz
/usr/share/man/man8/pcimodules.8.gz
/usr/share/man/man7/pcilib.7.gz
/usr/share/doc/pciutils/TODO.Debian
/usr/share/doc/pciutils/copyright
/usr/share/doc/pciutils/examples
/usr/share/doc/pciutils/examples/example.c
/usr/share/doc/pciutils/README.gz
/usr/share/doc/pciutils/changelog.Debian.gz
/usr/share/doc/pciutils/changelog.gz
/usr/bin/lspci
/usr/bin/setpci
/usr/bin/pcimodules
/usr/bin/update-pciids
只有四个命令,lspci 列出所接入 PCI 设备,setpci 设置 PCI 硬件参数,pcimodules 列出相关的 kernel modules,而 update-pciids 就是更新用于关联硬件编号和对应文本信息的数据文件(一般在 /usr/share/misc/pci.ids)。

这里介绍最基本的 lspci 和 setpci。

前者最有用的两个参数一个是 -vv,将会显示很多有用的信息(如果嫌多了可以 -v 或者不要,还觉得少了 -vvv 吧 -,-b);另一个是 -nn 显示数字编号同时也显示文本(-n 自己去猜吧 -,-b),某些参数的获取要求有 root 权限。一般有些什么信息呢?slots(插槽)、class、vendor(生产商)、device(设备名)、SVendor 和 SDevice(子系统对应的)、Rev(修正号)、ProgIf(是否可编程)、driver 和 module。

后者跟硬件比较相关的感觉。

lspci 在装显卡驱动的时候很有用...

后者

2008年9月21日星期日

gnupg

gnupg 亦即 GNU Privacy Guard,含有
/usr/lib/gnupg/gpgkeys_ldap
/usr/lib/gnupg/gpgkeys_curl
/usr/lib/gnupg/gpgkeys_finger
/usr/lib/gnupg/gpgkeys_hkp
/usr/lib/gnupg/gpgkeys_mailto
/usr/share/man/man7/gnupg.7.gz
/usr/share/man/man1/gpg-convert-from-106.1.gz
/usr/share/man/man1/gpg-zip.1.gz
/usr/share/man/man1/gpg.1.gz
/usr/share/man/man1/lspgpot.1.gz
/usr/share/man/man1/gpgsplit.1.gz
/usr/share/doc/gnupg/THANKS.gz
/usr/share/doc/gnupg/changelog.include.gz
/usr/share/doc/gnupg/faq.html.gz
/usr/share/doc/gnupg/changelog.Debian.gz
/usr/share/doc/gnupg/changelog.po.gz
/usr/share/doc/gnupg/changelog.cipher.gz
/usr/share/doc/gnupg/OpenPGP.gz
/usr/share/doc/gnupg/TODO.gz
/usr/share/doc/gnupg/highlights-1.4.txt.gz
/usr/share/doc/gnupg/FAQ.gz
/usr/share/doc/gnupg/changelog.g10.gz
/usr/share/doc/gnupg/Upgrading_From_PGP.txt.gz
/usr/share/doc/gnupg/changelog.checks.gz
/usr/share/doc/gnupg/changelog.toplevel.gz
/usr/share/doc/gnupg/DETAILS.gz
/usr/share/doc/gnupg/README.gz
/usr/share/doc/gnupg/changelog.tools.gz
/usr/share/doc/gnupg/changelog.util.gz
/usr/share/doc/gnupg/copyright
/usr/share/doc/gnupg/changelog.mpi.gz
/usr/share/doc/gnupg/NEWS.gz
/usr/share/gnupg/options.skel
/usr/bin/gpg
/usr/bin/gpg-zip
/usr/bin/gpg-convert-from-106
/usr/bin/gpgsplit
/usr/bin/lspgpot
/usr/share/doc/gnupg/changelog.gz
主要程序就是 gpg,用于加密和签名,gpg-zip 用于将文件归档后加密签名。现在 gpg 已经有新的 2.x 版本了,这里主要介绍 1.x。两者差异主要是构架上的,2.x 增加了 agent 来 caching、以及新的协议(X.509),这个我们会在后面慢慢介绍。这里主要介绍一些基本的用法。

为什么要用 gpg 这类程序?其一可以安全的存放自己的数据,通过 gpg 的不对称、对称密钥系统,可以轻松的加密文件。其二作为身份验证的绝佳手段(数字签名),避免身份欺骗。前者,有很多类似的工具,比如 openssl,还有文件系统级别的,那就更加的方便了,但是仍然有些应用,比如邮件,常用的还是 gpg。后者,得益于不对称密钥系统,每个用户产生自己的一堆密钥,保存好私钥,传播公钥。一般来说可以通过密钥的 fingerprint 验证拿到的是否为对方的公钥,还可以通过信任机制,在 keyserver 上获得。

常见的申请出国的同学被黑手写拒信抢了 offer,用好 gpg 这类工具就不会产生这种麻烦(不过要求对方也使用 gpg 验证)。另外很多实时聊天协议并没对传输文本加密,使用 gpg 也能获得这个效果。当然,比较好的是使用签名,如果文本本身并不敏感,避免出现自己机器被其他人使用,冒名顶替。著名的 pidgin 就有一个 pidgin-encryption 插件,可以实现这个功能。常见的有建客户端程序,如 thunderbird、kmail、mutt 都可以方便的使用 gpg。Windows 用户可以使用 gpg,还可以使用商业软件 pgp 以更好的支持诸如 outlook、outlook express 这种软件。

对于开发人员而言,签名还可以作为验证数据完整性的工具,这在发布软件的时候尤为有用

下面就让我们花点时间产生自己的 gpg 密钥,学习如何使用它实现最基本的功能吧。首先看看自己有没有产生自己的密钥,
gpg -k 或者 gpg --list-keys
这里列出来的是公钥,公钥一般用来给别人寄送加密文件时(注意公钥只能加密,加密后如果自己没有私钥是无法解密的;这也就是为什么多数邮件客户端寄送加密邮件时会要同时用自己的公钥加密,不然以后自己看自己发送的邮件都不知道是什么了)、或者验证他人签名时使用。如果是想看有没有私钥,则
gpg -K 或者 gpg --list-secret-keys

如果你不曾使用过 gpg,那么很可能两者都没有。这时候我们可以
gpg --gen-key
产生自己的密钥对。一般说来 DSA 使用于签名、ElGamal 用于加密,前者长度为 1024 bits,后者最长可以到 4096 bits。建议使用默认的,产生签名和加密的密钥。密钥会对应一个 user ID,通过姓名、电子邮件和备注(可选)确定的,后面我们会发现一个密钥里面可以添加多个 UID 和多个 subkeys,方便用户使用多个帐户、在不同地方使用不同的密钥。产生密钥需要随机数,gpg 会从系统很多地方采集 entropy(比较搞笑的是说使用 gpg --gen-random 产生随机数会降低系统的 entropy),这需要一定的时间。然后用户需要给一个 passphrase 保护密钥(也是 gpg 这个体系的最大弱点之一)。密钥有一个过期时间,这个可以修改,但建议最好是不要修改。我们假设产生的密钥 id 是 12345678(可以用 -k 看到)

密钥产生以后,应尽快制作一个吊销证书,这可以避免一旦密钥失效(如被人窃取、忘记 passphrase 了),可以使用该证书吊销密钥(主要是私钥),吊销而不是删除可以允许你还能访问曾经用该密钥加密的数据(删掉了自己就看不到了),但是程序会拒绝继续使用该密钥签名、加密。这个吊销证书的重要性不言而喻,因此应和私钥分开保存。使用
gpg --gen-revoke 12345678
产生一个吊销证书,注意这样调用可能会使得你的屏幕花掉(reset),我们可以通过 --output 指定输出到文件,这会产生 ASCII 输出,因此可以将它打印出来,保存到安全的地方,如保险柜、银行,需要的时候通过 OCR 识别即可。比如
gpg --output someone.revoke --gen-revoke 12345678

那么我们想到的最直接和其他 gpg 用户交互的方法,就是导出自己的 gpg public key,然后寄给对方,让我们在这里共享一下自己的 public key 吧。不过注意,直接
gpg --export 12345678
是会花屏的(reset 之),使用 --armor 可以将它变成 ASCII,然后还可以用 --output 啦(后面就不说了)。

当然,私钥也是能导出的,不过如果你的密钥在安全的地方,导出一份到不安全的地方反而不好。后面我们会谈到,可以导出一个 subkey 到其他的地方去用,如果泄露了尽早吊销就好了,不会影响主密钥。
gpg --output someone.sec --export-secret-key 12345678

拿到了别人的公钥后,首先要导入(这部分不存在信任,只是为了处理),然后确定信任关系,才能使用。到入只需要
gpg --import someone.pub
即可。那么我们怎么确定我们拿到的公钥就是声称是自己发布的那个人的呢?我们可以通过密钥的 fingerprint,
gpg --edit-key 12345678
进入到一个 shell 里面,使用 fpr 命令,我们应该通过绝对可靠的方式验证这个指纹,比如找他当面对比(电话... 其实也不安全的说)。一旦确认了这个,我们就可以信任该密钥了。首先,我们应该对该密钥签名(sign 或者 lsign),然后 check 发现该密钥上除了原来对方自己的签名,还有自己的签名。不过这时没有改变信任关系,仅仅是使得自己可以使用该签名加密了。

加密(-e)和解密(-d)很简单,使用对方的公钥可以
gpg --output file.enc --encrypt file

这会提示添加接受人,也可以用 --receipient 指定。解密需要对应的公钥,直接
gpg --output file --decrypt file.enc
即可。加密也可以使用 --armor 产生一个文本文件,体积会比较大;默认情况下会压缩后加密,体积较小。

事实上,也可以直接使用对称密钥(-c)给自己的文件加密,
gpg --output file.enc --symmetric file
解密方法与原来一样。

更重要的功能是签名,签名分为几种,一种签名和原文件放在一起,那只需要
gpg --output file.sig --sign file
即可,这时一般需要 --decrypt 该文件才能获得原来的文件;只需要验证的话,可以用
gpg --verify file.sig
这种签名也会压缩文件,而处理 Email 等文件我们不需要压缩(否则看起来麻烦)。我们选择 --clear-sign,这样就不会改动原文件。另外发布软件的时候,我们也多把签名和发布包分开,这就是所谓的 detached signature,
gpg --output file.sig --detach-sig file
验证的时候写两个参数即可,
gpg --verify file.sig file

下面我们看看如何管理我们的密钥,重要的命令是 --edit-key,这将会让我们进入一个 shell,通过各种命令修改我们手中的密钥,比如增加/删除/吊销 UID(对应多个帐号),增加/删除/吊销 subkeys(可以签名或者加密),指定某个 key 对应的 keyserver(后面介绍如何使用 key server 传播自己的密钥),各种 sign(lsign 只能本地使用不能导出,tsign 同是修改信认为 trust,nrsign 使得不能吊销,delsig 删除签名),添加照片(addphoto),expire 设置过期,primary 设置主 UID,设置信任(trust)等。

我们可以把添加之后的这些信息通过 --export 导出,同时用 gpgsplit 分成若干部分,每部分可以用 pgpdump 查看是否是有效的部分。比如
gpg --export-secret-key | gpgsplit -vp prefix
然后我们可以取一部分去组成新的 key,这里有一篇文章介绍如何修改 primary key 为 subkey,当然比较暴力了。比较文明的是用 --export-secret-subkey。

我们来看看 trust 的级别,分 full、marginal、none 和 unkown,如果是 trust,那么用户 sign 过的密钥的私钥 sign 过的密钥跟自己 sign 过的等同效力,也就是说相信这个人的朋友一定是你自己的朋友(他不会认错人);marginal 则不然,这只是表示信任当前密钥的有效性(我认识你而已,你认识的未必是我认识的);none 表示就不是有效的密钥;unknown 则表示对此一无所知。通过信任关系,可以形成一个有向图。一般信任规则如下:如果自己 sign 了;自己 trust 的人 sign 了;或者三个以上 marginal 信任的人 sign 了,那么就是有效的。或者在 trust 的有向图上,该人和你的最短距离是不超过 5。

利用这个信任关系,更好的方法是用 key server,这样每个人上传自己的 signature 就可以了。从服务器上下载,
gpg --keyserver serverurl --recv-key keyid
或者上传
gpg --keyserver serverurl --send-key keyid

最后提一下一些 frontend,gpg 自己也做了一个叫 gpa(用 gtk+ 写的,不过尚不好用,虽然自称懂得 gpg 的 frontend);GNOME 里面有 seahorse;KDE 里面原来是 kgpg,到了 KDE 4 似乎还有一个 kleopatra。懒得用命令行的人,或者图形界面整合比较方便的人可以玩玩。

2008年9月12日星期五

more, less and most

很早就听说了 more,似乎是 dos 时代的事情,后来发现似乎 more 起源不是 dos,进入 Linux 之后发现了 less,而现在又找到了一个 most。这些程序的主要任务是进行分页(pager),便于终端用户阅读超过一屏的文件或者程序输出。

less 意义上和 more 相反,因为 more 只能向后翻页,所以你只能获得 more content,而 less 则允许你向前翻页。下面是 less 相关的内容,
/usr/bin/less
/usr/bin/lesskey
/usr/bin/lessecho
/usr/bin/lesspipe
/usr/share/man/man1/lessecho.1.gz
/usr/share/man/man1/lesspipe.1.gz
/usr/share/man/man1/less.1.gz
/usr/share/man/man1/lesskey.1.gz
/usr/share/doc/less/LESSOPEN
/usr/share/doc/less/README.Debian
/usr/share/doc/less/copyright
/usr/share/doc/less/changelog.gz
/usr/share/doc/less/changelog.Debian.gz
/usr/lib/mime/packages/less
/usr/bin/lessfile
/usr/share/man/man1/lessfile.1.gz
一般 less 可以查看文件或者通过管道使用,在 less 查看内容时候可以用某些命令,这些命令来源于 more 或者 vi,

而 most 含有
/usr/bin/most
/usr/lib/mime/packages/most
/usr/share/doc/most/README
/usr/share/doc/most/changelog.Debian.gz
/usr/share/doc/most/changelog.gz
/usr/share/doc/most/copyright
/usr/share/doc/most/lesskeys.rc
/usr/share/doc/most/most-fun.txt
/usr/share/doc/most/most.rc
/usr/share/man/man1/most.1.gz
但是似乎比 less 强的就是可以分多个 screen 出来,可以同时打开几个文件阅览,每个打开的文件可以有自己的 mode。比较有用的就是 C-x 2 分屏,o 切换焦点,:n 到下一个文件。

2008年9月11日星期四

at

机缘巧合,不得不用,于是研究下吧:
/var/spool/cron/atjobs
/var/spool/cron/atspool
/etc/at.deny
/etc/init.d/atd
/etc/pam.d/atd
/usr/bin/batch
/usr/bin/at
/usr/share
/usr/share/man/man8/atd.8.gz
/usr/share/man/man1/at.1.gz
/usr/share/man/man5/at.allow.5.gz
/usr/share/doc/at/copyright
/usr/share/doc/at/readme.txt.gz
/usr/share/doc/at/changelog.gz
/usr/share/doc/at/timespec
/usr/share/doc/at/changelog.Debian.gz
/usr/share/doc/at/Problems
/usr/sbin/atd
/usr/bin/atq
/usr/bin/atrm
/usr/share/man/man1/atq.1.gz
/usr/share/man/man1/batch.1.gz
/usr/share/man/man1/atrm.1.gz
/usr/share/man/man5/at.deny.5.gz
其主要的功能是在指定的时间执行指定的程序(at),也可以在系统负荷较低的时候执行(batch)。

at 命令和 batch 用法类似,通过 at TIME 就会获得一个提交命令的 prompt,也可以把命令写入一个文件,然后 -f 指定。-q 可以指定一个 queue(字母 a-zA-Z 指定,获得不同的 nice)。-l 和 atq 作用一样,-d 和 atrm 一样。另有 -c 显示命令到 stdout 和 -v 显示执行时间。配置文件主要是 /etc/at.allow 和 /etc/at.deny,存在前者时仅有里面的用户可以用 at,如果不存在根据后者文件内容拒绝用户(为空时拒绝所有用户)。

atd 是 at 的 daemon,可以指定一个 average load 供 batch 判断是否可以执行任务。

如何声明时间呢?这个是非常的自由的,如果想看看语法,可以参考 /usr/share/doc/at/timespec,用绝对的时间,如 23:11 或者 10:00 pm 等写法都可以,后面可以用 Sep 16 2008 等指定日期。还可以用相对的时间如 now + 4h 获得四小时以后执行的任务。

2008年9月4日星期四

Linux 下的无线网络配置(一)

到现在我使用的无线网卡仅仅局限在 D-Link 的 DWL-G650,这使用的是 atheros 芯片,驱动是 madwifi 提供的,不过有的无线网卡现在的内核已经直接可以驱动了,使用的某些工具和本文类似。不过值得注意的是,将来可能会使用 ath5k 或者 ath9k 的驱动,而不是用 madwifi + hal 的构架了。

相关的包有:
  • madwifi-source 提供 madwifi 的源代码。
  • madwifi-tools 提供一些关于 atheros 芯片的一些程序。
  • wireless-tools 提供配置无线网络的基本命令。
  • wpasupplicant 为无线网络提供 WPA 支持。
  • dhcp3-client 提供 DHCP 配置网络功能。
通过 debian 的 module assistant 安装 madwifi 提供的内核模块,这样就可以避免后期的维护工作,这可以通过
# m-a prepare madwifi
# m-a a-i madwifi
完成。这样就会把 ath_* 等内核模块加载。然后可以用 madwifi-tools 工具创建几个设备。该包主要提供了
/usr/sbin/athstats
/usr/sbin/ath_info
/usr/sbin/80211debug
/usr/sbin/athdebug
/usr/sbin/athkey
/usr/sbin/athchans
/usr/sbin/80211stats
/usr/sbin/athctrl
/usr/share/man/man8/ath_info.8.gz
/usr/share/man/man8/wlanconfig.8.gz
/usr/share/man/man8/80211stats.8.gz
/usr/share/man/man8/athkey.8.gz
/usr/share/man/man8/80211debug.8.gz
/usr/share/man/man8/athctrl.8.gz
/usr/share/man/man8/athchans.8.gz
/usr/share/man/man8/athdebug.8.gz
/usr/share/man/man8/athstats.8.gz
/usr/share/doc/madwifi-tools/README.Debian
/usr/share/doc/madwifi-tools/changelog.Debian.gz
/usr/share/doc/madwifi-tools/copyright
/etc/modprobe.d/madwifi
/etc/network/if-pre-up.d/050madwifi
/etc/network/if-post-down.d/z50madwifi
/sbin/wlanconfig
主要的工具就是 wlanconfig。

首先澄清的一个概念是 atheros 芯片支持多个 VAP,共享在一个物理的无线网卡上。使用 ifconfig 可以获得一个 wifi0 的 interface,这个就是物理设备本身。使用 VAP 的好处是可以产生多个不同类型(mode)的 VAP 分别进行连接。那么 VAP 有些什么类型呢?
  • ahdemo 是另一种 ad-hoc demo (aka pseudo IBSS) mode 模式的 station。
  • adhoc 亦即 ad-hoc mode 的 station,该状态下不需要 AP 就可以互相连接,应该是作为两台笔记本直接联机的用途。
  • ap 亦即 AP mode,这个存在的目的是为了把自己的网卡变成一个 AP,但是可以存在多个 AP mode 的 VAP。自己的网卡作为一个 AP,就可以进行网络的桥接,做好适当的 routing 配置好 forwarding 就能实现很多好玩的功能了。
  • monitor 创建一个 monitor mode 的 station,这个模式类似于网卡的混杂模式。
  • sta 即 station mode,默认情况下(加载 ath_pci 模块时)创建的 VAP 类型,局限在于如果是该设备上第一个 VAP,后面就不能再创建其他的 VAP;但是如果不是第一个创建则可以创建多个不同的 VAP,但是 sta 只能有一个。
  • wds 亦即 WDS mode 下的 station,一般可以直接通过 iwpriv 修改一个 VAP 的对应功能。
我们最常用的可能就是 sta 模式了,这时我们作为一个 client 连接到某个 AP 上工作。后面我们将介绍几种最可能用到的连接方式:
  • sta + phycical AP 最常用无线网络,自己的无线网卡和别人提供的 AP 连接。
  • ad-hoc + ad-hoc 双机对联,两个无线网卡之间联机。
  • monitor 用于窃听,如捕获无线网络中数据,破解 WEP 密码等。
  • ap + sta 一个网卡作为 ap,一个作为 sta 进行连接。
对于桥接等比较高级的话题,等到对网络本身熟悉到足够程度后就知道怎么作了。

对 sta + physical AP 这个模式,我们首先需要创建 sta 模式下的 VAP,这一般在加载 ath_pci 时已经自动的完成了,很可能直接 ifconfig ath0 up 就能看见了,如果没有,可以用
# wlanconfig ath create wlandev wifi0 wlanmode sta
获得,然后我们需要通过该设备获得环境中可以连接的 AP,这部分就开始依靠 wireless-tools 的工具了。如果后面讲到创建 ap 模式的 VAP,我们可能需要去除掉该 VAP,这一般是
# wlanconfig destroy ath0
完成,类似的可以知道如何建立其他的 VAP 并将其销毁。

在 madwifi-tools 里面还有一些其他的工具:
  • athstats 显示物理设备网络负载等统计信息。
  • ath_info 显示 module 的信息、写 eeprom 信息(可以改变通信频段)。
  • 80211debug 用于在 madwifi 的 802.11 栈中设置或者清除调试信息。
  • athdebug 设置或者清除 madwifi 子系统的调试信息。
  • athkey 用于设置 wifiN 设备的四个 key,如 wep 等。
  • ahtchans 设置 wifiN 设备的频道范围。
  • 80211stats 用于显示 802.11 的统计信息。
  • athctrl 用于显示通讯的 stations 之间的最大距离。
  • wlanconfig 除了创建/销毁需要的 VAP 以外,还有 list 功能,如 wlanconfig ath0 list scan 将会列出搜索到的所有 AP 的信息。

下面我们来看 wireless-tools 的作用,这是里面含有的内容:
/sbin/iwconfig
/sbin/iwevent
/sbin/iwgetid
/sbin/iwlist
/sbin/iwpriv
/sbin/iwspy
/usr/share/man/man8/iwconfig.8.gz
/usr/share/man/man8/iwevent.8.gz
/usr/share/man/man8/iwgetid.8.gz
/usr/share/man/man8/iwlist.8.gz
/usr/share/man/man8/iwpriv.8.gz
/usr/share/man/man8/iwspy.8.gz
/usr/share/man/man7/wireless.7.gz
/usr/share/doc/wireless-tools/README.Debian
/usr/share/doc/wireless-tools/copyright
/usr/share/doc/wireless-tools/DISTRIBUTIONS.txt.gz
/usr/share/doc/wireless-tools/PCMCIA.txt.gz
/usr/share/doc/wireless-tools/HOTPLUG.txt.gz
/usr/share/doc/wireless-tools/README.gz
/usr/share/doc/wireless-tools/changelog.Debian.gz
/usr/share/doc/wireless-tools/changelog.gz
/etc/network/if-pre-up.d/wireless-tools
/etc/network/if-post-down.d/wireless-tools
这里面最重要的命令是 iwconfig 和 iwpriv。iwconfig 用于配置一些比较 general 的功能,如 ESSID、AP 的 MAC 地址、mode、频道、速率等。和 ifconfig 类似,不加任何参数的时候显示 /proc/net/wireless 的内容;而 iwpriv 则配置比较 private 的内容,和各个网卡相关的东西,可以用 -a 获得所有可以执行的命令。下面是这些命令的说明:
  • iwevent 显示 wireless 事件,主要是驱动程序或者配置更新的事件。
  • iwgetid 获得当前连接网络的信息,相对于 iwconfig 更适合写脚本使用。
  • iwlist 用于显示无线网络的各种信息,通过 scaning 网络中 AP 获得。
  • iwspy 用于获取无线网络某些节点上的统计信息。

那么,当我们通过 wlanconfig 创建了 sta 后,就应该利用该 ath0 获得可供连接的无线网络,这可以使用
# iwlist ath0 scan
得到一个列表,然后通过
iwconfig ath0 essid something
设置对应的 ESSID,或者也可以用诸如 MAC 地址之类的东西获得连接。在我的无线网卡上,如果没有驱动,会单灯慢速闪烁,另外一个灯熄灭;如果有驱动,插上后,一灯熄灭一灯亮起。使用 iwconfig 指定了连接的 AP 后则会双灯闪烁,这时候我们应该根据 iwlist 列出来的信息,如是否加密设置相应的密码。无线网络和有线网络一样都可以被监听,但是无线的特性使得这个问题更加严重。这个问题往往使用 link-layer 加密解决。如使用的 WEP 加密,可以直接用
# iwconfig ath0 enc ...
命令设置密码,如果是 WPA 类型,我们需要 wpasupplicant,这个包里面含有:
/etc/dbus-1/system.d/wpa_supplicant.conf
/etc/logrotate.d/wpa_action
/etc/logrotate.d/wpa_supplicant
/etc/wpa_supplicant/ifupdown.sh
/etc/wpa_supplicant/functions.sh
/etc/init.d/wpa-ifupdown
/usr/bin/wpa_passphrase
/usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service
/usr/share/doc/wpasupplicant/NEWS.Debian.gz
/usr/share/doc/wpasupplicant/examples
/usr/share/doc/wpasupplicant/examples/wep.conf
/usr/share/doc/wpasupplicant/examples/wpa2-eap-ccmp.conf
/usr/share/doc/wpasupplicant/examples/wpa-roam.conf
/usr/share/doc/wpasupplicant/examples/openCryptoki.conf
/usr/share/doc/wpasupplicant/examples/ieee8021x.conf
/usr/share/doc/wpasupplicant/examples/wpa-psk-tkip.conf
/usr/share/doc/wpasupplicant/examples/plaintext.conf
/usr/share/doc/wpasupplicant/changelog.Debian.gz
/usr/share/doc/wpasupplicant/copyright
/usr/share/doc/wpasupplicant/changelog.gz
/usr/share/doc/wpasupplicant/README.wpa_supplicant.conf.gz
/usr/share/doc/wpasupplicant/README.gz
/usr/share/doc/wpasupplicant/README.Debian.gz
/usr/share/man/man8/wpa_action.8.gz
/usr/share/man/man8/wpa_passphrase.8.gz
/usr/share/man/man8/wpa_cli.8.gz
/usr/share/man/man8/wpa_supplicant.8.gz
/usr/share/man/man8/wpa_background.8.gz
/usr/share/man/man5/wpa_supplicant.conf.5.gz
/sbin/wpa_action
/sbin/wpa_cli
/sbin/wpa_supplicant
/etc/network/if-up.d/wpasupplicant
/etc/network/if-down.d/wpasupplicant
/etc/network/if-post-down.d/wpasupplicant
/etc/network/if-pre-up.d/wpasupplicant
/usr/share/doc/wpasupplicant/README.modes.gz
这里面主要的两个命令是 wpa_passphrase 和 wpa——supplicant,前者用于产生需要的密钥信息,后者用于给指定的设备添加 WPA。一般利用
wpa_passphrase essid passphrase
生成一段信息,将其置入某个文件,然后用 wpa_supplicant 这个 daemon 产生需要的加密:
wpa_supplicant -B -Dwext -iath0 -c file
下面是一些其他程序的介绍:
  • wpa_supplicant 其中 -D 选择的是 wireless 的 driver 类型,-i 指定 interface(-N 可以指定多个)。
  • wpa_action 对指定 interface 发布指定的命令。可以用 wpa_cli 调用该命令。
  • wpa_cli 是一个文本界面下和 WPA 交互的客户端。

一般通过 ifconfig ath0 up 启动了对应的 interface 后,需要配置 IP 地址,这可以用 dhclient 通过 DHCP 实现动态的配置,这在 dhcp3-client 包中。

下面我们就其他的几种情况讲解如何配置无线网络:
ad-hoc + ad-hoc:

2008年8月12日星期二

expect

expect 是一种脚本语言,用于编程者与文本界面下交互式程序交互。expect 使用的是 tcl 程序语言,但是 expect 支持一些自己的特殊命令用于实现交互过程。在 debian 的包里,有如下的一些文件:
/usr/bin/expect
/usr/lib/expect5.43/pkgIndex.tcl
/usr/lib/expect5.43/libexpect5.43.a
/usr/lib/libexpect.so.5.43.0
/usr/share/doc/expect/changelog.gz
/usr/share/doc/expect/FAQ.gz
/usr/share/doc/expect/ChangeLog.gz
/usr/share/doc/expect/changelog.Debian.gz
/usr/share/doc/expect/README.gz
/usr/share/doc/expect/copyright
/usr/share/doc/expect/NEWS.gz
/usr/share/man/man1/expect.1.gz
/usr/share/man/man3/libexpect.3.gz
/usr/share/lintian/overrides/expect
/usr/lib/libexpect.so.5
/usr/lib/libexpect.so.5.43
这包括了解释器 expect,也提供了 C/C++ 程序接口库 libexpect.so。

expect 执行的基本方式是,通过自身激活需要交互的程序,并控制该程序的输入输出,这样可以选择通过 expect 脚本与该程序交互(通过分析程序输出内容产生合适的输入),也可以在合适的时候释放对该程序输入输出的控制。因此 expect 本身提供不同于 tcl 的部分主要是在处理这部分功能上。我们会在后面的文章中对 tcl 语言进行简单的介绍,这里仅仅介绍一些 expect 特有的命令:
  • close 用于关闭 expect 打开进程的 stdin,这往往会向该进程发送 EOF,多数程序(如 mail 等)会因此退出,但是不是一定会结束进程(因此可能需要通过 wait 等候进程结束)。-slave 将会把关联到该进程的 pty 也一同关闭。-i 可以指定 spawn id。-onexec 可以为 0 或者非 0,默认为 0 表示该 spawn id 后续进程不受其影响。
  • debug 打开 tcl 调试工具,-now 1 打开调试,-now 0 关闭。
  • disconnect 将一个进程从前台转到后台,这时它的 stdout 等被重定向到 /dev/null。和直接使用 & 不同的地方在于,expect 会存储对应 terminal 信息以便后面将该进程连接到其他的 pty 上。
  • exit 退出该 expect 进程,fork 或者 spawn 的进程根据自己处理 EOF 的方式决定成活。
  • exp_continue 一般在 expect 命令中使用,它可以避免写第二次 expect 命令,即如果匹配上某个模式,然后需要做一些事情(如输入密码什么的),之后需要继续匹配,因此需要第二次 expect 命令。exp_continue 可以重复本次 expect 命令,因此也就不需要再次写一个 expect 命令,而可以将两个写在一起。
  • exp_internal 可以让后续命令的诊断信息发送到 Expect 所控制的 stderr 或者 -f 指定的文件。如果 exp_internal 0 则关闭该功能,非零则打开该功能。
  • exp_open 用来打开(-i)指定的 spawn id,这样打开后对应的 spawn id 不可以再被使用。一种理解是 spawn id 是 expect 层次上交互需要的 id,而通过 exp_open 之后获得的是 tcl 层次上的 id。
  • exp_pid 可以获得(-i)指定的 spawn id 对应的 PID。
  • exp_send 是 send 的别称,send 将指定字符串发送给(-i)对应的进程。-null 发送 ASCII 0 字符,-break 没看懂,-s 慢速发送字符,-h 模仿人打字的速度。
  • exp_send_error 是 send_error 的别称,和前者类似,但是发送到 stderr。
  • exp_send_log 是 send_log 的别称,和前者类似,但是发送到 log file。
  • exp_send_tty 是 send_tty 的别称,和前者类似,但是发送到 /dev/tty。
  • exp_send_user 是 send_user 的别称,和前者类似,但是发送到 stdout。
  • exp_version 可以用来保证源代码解释的 expect 版本,通过 -exit 强制在不合适的情况退出。
  • expect 是最重要的命令,它通过匹配某个 spawn 程序的输出执行某个命令,如输出某些与该程序交互或者转移对程序的控制等等。基本的用法是 -opt pat command,即通过 -opt 指定特定的属性(如 spawn id 等),然后匹配 pat,执行 command(多个 command 可以用 {} 括起来,同行命令用 ; 分隔),一个 expect 可以带有多组这种结构应对不同的情况。常用的 opt 有 -i 指定 spawn id,-re 使用 tcl 的正则表达式,-ex 进行精确匹配(如忽视 ^ 和 $ 表达字符串首尾的意思,和一般 RE 里面使用行首行尾是不同的),-nocase 不区分大小写。pat 可以用关键字如 eof、timeout(超时用 set timeout 设置,默认是 10s)、default(eof 或者超时)。或者用 glob 方式匹配(有空格时应该用引号引起来)。匹配时 expect 维护一个 buffer,默认容纳 2000 字节(可用 match_max 函数设定),因此超过该长度的输出会被截断。匹配时,会设置一些相关的变量,如 expect_out(buffer) 是匹配上的内容及其之前没匹配上的内容,剩下的还在 buffer 里可供下次继续匹配。另外 expect_out(X, string/start/end) 在 X=0 时表示匹配上的整个字符串及其始末位置,而 X = 1..9 时表示每一个匹配部分的类似信息(需要 -indeices)。每个 spawn id 对应的 buffer 在 expect_out(spawn id)。不使用 -i 指定 spawn id 时,使用的是 any_spawn_id 这个变量。
  • expect_before 和 expect_after,这两个作为 expect 的补充,一个有限比 expect 高,一个低。
  • expect_background 在后台匹配,因此不存在 timeout,同时会立即返回。在执行匹配好后的命令时会 block 后台处理。
  • expect_tty 和 expect_user 与 expect 类似,但是输入来源分别是 /dev/tty 和 stdin,一般需要用户回车后才能匹配,可以通过 stty 改变 tty 的模式不需要回车也能匹配。
  • fork 产生一个新的 expect 进程,子进程返回 0,一般在 spawn 前 fork 比较安全。
  • interact 是一个非常重要的命令,它允许用户参与到交互过程中,它捕获用户的输入进行匹配(用户自定义的字符串),如果匹配成功(和 expect 不同之处是这里都是精确匹配)则执行用户自定义的命令。格式为 -opt string command。其中 opt 可以是 reset 表示将 terminal 设置成为 interact 命令前的状态,re 打开正则表达式匹配,iwrite 将 interact(spawn_id) 设置为该 spawn id,echo 将用户输入直接回显(如果没匹配上就会显示两遍),nobuffer 将直接把输入字符输出到进程,u spawn_id 可以让用户与指定 spawn_id 交互,input/output 用于控制指定 spawn id 的输入输出(如果没有 output 则丢弃)。string 可以是 eof、timeout N(表示等待的时间)、null(接受到 ASCII 码 0)。一种用法就是利用 expect 提供更简单的命令名。
  • interpreter 打开 expect/tcl 的解释器,用于交互执行 expect 命令。
  • log_file 记录会话过程,可以通过 -a 指定文件,可以提供 tcl 文件 identifier(-open、-leaveopen)。
  • log_user 记录 expect 和 send 会话,log_user 0 关闭,log_user 1 打开。
  • match_max 设定 expect 匹配的 buffer 大小。
  • overlay 将该 expect 进程用指定程序代替,可以通过 -n 指定 stdin/out/err 对应绑定的进程(类似于管道)。
  • parity 没看懂...
  • remove_nulls 决定 spawn 进程的 null 是不是被去掉。
  • sleep 休息若干秒。
  • spawn 启动一个进程,并设定几个相关的变量,如 spawn_id 包含该进程的信息(expect 根据这个判断输出),user_spawn_id 含有的是和用户相关的信息(因此将 spawn_id 设为此值就成为了 expect_user),类似还有 error_spawn_id 和 tty_spawn_id。spawn_out(slave,name) 是该进程连接到的 pty。-ignore 将使得进程忽略掉某些信号。
  • strace 提供调试程序的功能。
  • stty 和外部命令 stty 类似,设定 terminal 的模式,-raw 还是 -cooked。开关回显 echo 和 -echo。
  • system 执行某个命令,和 exec 不同之处在于并不将其输入输出定向到 /dev/tty。
  • timestamp 返回时间戳。
  • trap 将对应的 signal 绑定到某个 command,即设置 signal handler。
  • wait 等候 spawn 进程结束。
需要使用 C 程序接口可以用 libexpect。

下面是一个建立 ssh tunnel 的简单例子:
#!/usr/bin/expect -f

while {1} {
spawn ssh host -R 52028:127.0.0.1:22 -N
wait
sleep 60
}

2008年7月30日星期三

GSL

GSL(GNU Scientific Library)是一个 C 写成的用于科学计算的库,下面是一些相关的包
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name Version Description
+++-====================================-==========================-============================================
un gsl (no description available)
ii gsl-bin 1.11-2 GNU Scientific Library (GSL) -- binary packa
ii gsl-doc-pdf 1.11-2 GNU Scientific Library (GSL) Reference Manua
un gsl-ref-html (no description available)
un gsl-ref-pdf (no description available)
pn gsl-ref-psdoc (no description available)
un libgsl0 (no description available)
ii libgsl0ldbl 1.11-2 GNU Scientific Library (GSL) -- library pack
其中,libgsl0ldbl 是真正的库:
/usr/lib/libgsl.so.0.12.0
/usr/lib/libgslcblas.so.0.0.0
/usr/share/doc/libgsl0ldbl/changelog.Debian.gz
/usr/share/doc/libgsl0ldbl/changelog.gz
/usr/share/doc/libgsl0ldbl/THANKS.gz
/usr/share/doc/libgsl0ldbl/BUGS.gz
/usr/share/doc/libgsl0ldbl/README
/usr/share/doc/libgsl0ldbl/AUTHORS
/usr/share/doc/libgsl0ldbl/SUPPORT
/usr/share/doc/libgsl0ldbl/TODO.gz
/usr/share/doc/libgsl0ldbl/copyright
/usr/share/doc/libgsl0ldbl/NEWS.gz
/usr/share/lintian/overrides/libgsl0ldbl
/usr/lib/libgsl.so.0
/usr/lib/libgslcblas.so.0
另外还有一个相关的 gsl-bin,里面主要两个程序,
/usr/share/man/man1/gsl-histogram.1.gz
/usr/share/man/man1/gsl-randist.1.gz
/usr/share/doc
/usr/share/doc/gsl-bin
/usr/share/doc/gsl-bin/changelog.Debian.gz
/usr/share/doc/gsl-bin/changelog.gz
/usr/share/doc/gsl-bin/copyright
/usr/bin
/usr/bin/gsl-randist
/usr/bin/gsl-histogram
gsl-randist 和 gsl-histogram 分别是产生随机样本和计算直方图的程序。

我们这里根据 gsl-doc-pdf 给出如何使用 GSL 的程序接口和例程。GSL 的程序使用的头文件一般放在 /usr/include/gsl/ 目录(libgsl0-dev),C 程序通常用 #include 让预处理程序 cpp 读入对应的函数、宏声明,连接的时候通过 -lgsl -lgslcblas 到对应的库,通常还可能连接到 -lm。为了使用某些 inline 函数,可以打开 HAVE_INLINE 宏。注意由于 long double 和使用平台相关,一般不推荐使用。

GSL 里面的命名规则大致是使用 gsl 作为前缀(没有 namespace,sigh),函数的话一般是 gsl_foo_fn(对应 double)其余的为 gsl_foo_type_fn,对于类型一般是 gsl_foo 或者 gsl_foo_type(没有 template,sigh again)。对应的头文件一般是 gsl_foo.h(含有所有的类型)或者 gsl_foo_type.h。

GSL 里面出错处理遵循 POSIX 线程库,正常返回 0,出错返回非零,并依照 gsl_errno.h 里面设置出错值。可以用 gsl_strerror 将返回值用字符串表达出来。默认情况下 GSL 提供的 error handler 就是打印出错问题并调用 abort,这是一个 gsl_error_handler_t 类型的函数,可以通过 gsl_set_error_handler() 函数设定。

Mathematical Functions 常用数学函数 gsl_math.h
包括常用的数学常数(M_*),GSL_POSINF、GSL_NEGINF、GSL_NAN 以及相应判断的函数 gsl_isnan()、gsl_isinf() 和 gsl_finite()。另外提供了一些函数值快速计算的方法,gsl_log1p() 计算 log( 1 + x),gsl_exp1m() 计算 ex-1,gsl_hypot() 和 gsl_hypot3 计算欧氏空间范数,gsl_acosh()、
gsl_asinh()、gsl_atanh() 是反双曲函数,gsl_ldexp(x, y) 计算 x . 2y,gsl_frexp() 计算在二进制下科学记数法下 x 的基数部分。求幂次 gsl_pow_int 或者 gsl_pow_n(n = 2, ..., 9)。测试符号 GSL_SIGN,奇偶性 GSL_IS_EVEN 和 GSL_IS_ODD。取大小 GSL_MAX、GSL_MIN。浮点数大小最好用 gsl_fcmp 函数。

Complex Numbers 复数 gsl_complex.h、gsl_complex_math.h
定义一个复数可以用 gsl_complex_rect 或者 gsl_complex_polar,另外获得实部、虚部 GSL_REAL 和 GSL_IMAG,设定 GSL_SET_COMPLEX,GSL_SET_REAL 和 GSL_SET_IMAG。可以求辐角 gsl_complex_arg()、模长 gsl_complex_abs()、模长平方 gsl_complex_abs2、模长对数 gsl_complex_logabs()。复数的加减乘除就是 gsl_complex_op() 其中 op 可以为 add、sub、mul 和 div,另外和实数有类似的运算 gsl_complex_op_real(),和虚数有 gsl_complex_op_imag(),共轭 gsl_complex_conjugate()、逆 gsl_complex_inverse() 和相反数 gsl_complex_negative。另外如求平方根 gsl_complex_sqrt(对实数求加 _real),幂次 gsl_complex_pow(次数为实数加 _real),指数 gsl_complex_exp,对数 gsl_complex_log(loh10 或者 log_b)。另外还有三角函数、反三角函数、双曲函数、反双曲函数。

Polynomial 多项式 gsl_poly.h
一般可以给定多项式的系数,用一个数组从低阶到高阶,调用 Horner 法求多项式函数值可以用 gsl_poly_eval(),对复数而言是 gsl_poly_complex_eval(),对复系数多项式为 gsl_complex_poly_complex_eval()。另外一种表达方式是使用 Newton 差分法表达,这时输入的是差分节点创建一个多项式,gsl_poly_dd_init(),求函数值可用 gsl_poly_dd_eval(),还可以把这种类型的多项式转换成为 Taylor 展开的形式 gsl_poly_dd_taylor()。对二次多项式求解根可以用 gsl_poly_solve_quadratic(),复根可以用 gsl_poly_complex_solve_quadratic()。对三次方程用 cubic 替换 quadratic。对高于 4 次的多项式没有解析解,往往用矩阵特征值进行近似,GSL 提供了一种解法,首先用 gsl_poly_complex_workspace_alloc() 分配储存根的空间,然后调用 gsl_poly_complex_solve() 求解,求解之后应该用 gsl_poly_complex_workspace_free() 释放。

Special Functions 特殊函数 gsl_sf.h、gsl_sf_*.h
一般有两种调用形式,一种和正常函数类似直接 gsl_sf_function(),另一种是 gsl_sf_function_e() 将返回值的地址传入函数。gsl_sf_result.h 提供了一个用于估计误差的结构体,一般函数有三个 mode 控制计算精度 GSL_PREC_DOUBLE、GSL_PREC_SINGLE 和 GSL_PREC_APPROX。提供的特殊函数有 airy(见 gsl_sf_airy.h)的函数值、零点、导数、导数零点,Bessel 函数(见 gsl_sf_bessel.h)的函数值、零点,Clausen 函数(见 gsl_sf_clausen.h),Coulomb 函数(见 gsl_sf_coulomb.h),Coupling 系数(见 gsl_sf_coupling.h),Dawson 函数(见 gsl_sf_dawson.h),Debye 函数(见 gsl_sf_debye.h),Dilogorithm 函数(见 gsl_sf_dilog.h),乘法误差函数(见 gsl_sf_elementary.h),椭圆积分(见 gsl_sf_ellint.h),Jacobi 椭圆函数(见 gsl_sf_elljac.h),误差函数(见 gsl_sf_erf.h,GNU libc 也有类似的函数),指数函数(见 gsl_sf_exp.h),指数积分(见 gsl_sf_expint.h),Fermi-Dirac 函数(见 gsl_sf_fermi_dirac.h),Gamma 和 Beta 函数(见 gsl_sf_gamma.h),Gegenbauer 函数(见 gsl_sf_gengenbauer.h),超几何函数(见 gsl_sf_hyperg.h),Laguerre 函数(见 gsl_sf_laguerre.h),Lambert W 函数(见 gsl_sf_lambert.h),Legendre 函数和球面调和函数(见 gsl_sf_legendre.h),对数及其相关函数(见 gsl_sf_log.h),Mathieu 函数(见 gsl_sf_mathieu.h),幂函数(见 gsl_sf_pow_int.h),Psi(digamma) 函数(见 gsl_sf_psi.h),Synchrotron 函数(见 gsl_sf_synchrotron.h),transport 函数(见 gsl_sf_transport.h),三角双曲函数(见 gsl_sf_trig.h),Zeta 函数(见 gsl_sf_zeta.h)。

Vectors and Matrices 向量与矩阵 gsl_block.h、gsl_vector.h、gsl_matrix.h
创建 vector 也好、matrix 也好,都依赖 gsl_block 这个结构,可以用 gsl_block_alloc() 和 gsl_block_calloc() 分配,gsl_block_free() 释放,另外有对流的输入输出,如 gsl_block_fread()、gsl_block_fwrite()、gsl_block_fprintf() 和 gsl_block_fscanf()。不管是 vector 还是 matrix 都含有一个 gsl_block 的指针,操作和 block 类似。如 vector 的的类似操作就是 gsl_vector_alloc()、
gsl_vector_calloc()、gsl_vector_fread()、gsl_vector_fwrite()、gsl_vector_fprintf() 和 gsl_vector_fscanf(),另外可以通过 gsl_vector_get() 和 gsl_vector_set() 获得/设定某一分量的值,gsl_vector_ptr() 和 gsl_vector_const_ptr() 获得一分量的地址,另外有一些函数方便初始 vector,如 gsl_vector_set_all()、gsl_vector_set_zero() 和 gsl_vector_set_basis()。为了访问一个 vector 元素的子集,可以使用 vector view 对象,这可以用一些函数产生(有对应的 const 版本),并最好仅仅在 stack 内使用(也就是直接操作对象本身,而不是指针),如 gsl_vector_subvector() 产生一个连续的子集,gsl_vector_subvector_with_stride() 产生一个带固定间隔的子集,gsl_vector_complex_real() 和 gsl_vector_complex_imag() 产生一个 real 或者 image 部分的 view,gsl_vector_view_array() 对一个数组产生 vector view,gsl_vector_view_array_with_stride() 产生带有固定间隔的 vector view。vector 之间的复制或者互换有 gsl_vector_memcpy() 和 gsl_vector_swap()。vector 元素之间互换 gsl_vector_swap_elements(),逆序 gsl_vector_reverse()。vector 之间的四则运算 gsl_vector_op(),数乘(op = scale),加上常数(op=add_constant)。vector 最大最小(op=max、min、minmax)或者对应的 index(op = max_index、min_index、minmax_index)。判断一个 vector 是否为 0 向量(op=isnull),正(ispos),负(isneg),非负(isnonneg)。matrix 和 vector 稍微不同之处在于用两个下标索引,前面函数多数只要把 vector 换成 matrix 即可。另外还可以为 matrix 的行或者列建立 view,gsl_matrix_(sub)row/column(),或者对角元素 gsl_matrix_(sub, super)diagonal()。将矩阵一行/列读到/写到一个 vector 可以用 gsl_matrix_get/set_row/col()。矩阵行列互换 gsl_matrix_swap_rows/columns() 或者方阵的行列交换 gsl_matrix_swap_rowcol(),转置或转置复制 gsl_matrix_transpose()、gsl_matrix_transpose_memcpy()。矩阵运算中 mul_elements 和 div_elements 是对元素的。

Permutations 置换 gsl_permutation.h
这是产生置换的基本数据结构,一般用 gsl_permutation_(c)alloc() 分配内存,gsl_permutation_init() 初始化为置换幺元,可以用 gsl_permutation_memcpy() 进行复制,gsl_permutation_free() 释放。访问置换元素可以用 gsl_permutation_get(),互换用 gsl_permutation_swap()。另外可以用 gsl_permutation_size() 获得置换大小,gsl_permutation_data() 获得指向置换的指针,gsl_permutation_valid() 验证是否为合法的 permutation。另外有一些置换的操作,如 gsl_permutation_reverse() 逆转,gsl_permutation_inverse() 求逆,依照字典序计算下一个/前一个有 gsl_permutation_next/prev()。将 permutation 应用到数组上可以用 gsl_permute,或者逆 psl_permute_inverse(),对 vector 可以 gsl_permute_vector(_inverse)(),几个置换可以相乘 gsl_permutation_mul()。类似的 permutation 也有输入输出函数。另外置换存在一种正则表达方式可以用 gsl_permutation_linear_to_canonical() 转换,可以计算一个 permutation 含有几个 cycle 等。

Combinations 组合 gsl_combination.h
和置换类似的结构,但是处理的是组合问题。

Sorting 排序 gsl_heapsort.h、gsl_sort_*.h
首先提供了一个 quick sort 的补充的 heapsort,gsl_heapsort() 和 gsl_heapsort_index()。排序数组 or vector 可以用 gsl_sort() 或者 gsl_sort_vector(),另外也有带索引的版本。求最小/大的 k 个元素,可以用 gsl_sort(_vector)_smallest/largest(_index)()。

BLAS Support 基本线性代数子程序支持 gsl_blas.h、gsl_cblas.h
BLAS 支持三个 level 的运算,level 1 是 vector 的,level 2 是 matrix-vector 的,level 3 是 matrix-matrix 的操作。操作对象的类型为 SDCZ 对应 float、double、float complex 和 double complex,矩阵的特性为 GE(一般)、GB(一般带状矩阵)、SY(对称)、SB(对称带状)、SP(对称,packed)、HE、HB、HP(Hermite)、TR、TB、TP(三角阵)。操作类型有 DOT(内积)、AXPY(a x + y)、MV(矩阵 x 向量)、SV(矩阵逆乘向量)、MM(矩阵相乘)、SM(矩阵的逆乘另外一个矩阵)。GSL 提供的命令形式为 gsl_blas_*。

Linear Algebra 线性代数 gsl_linalg.h
这部分包括了最常用的数值线性代数运算,如矩阵 LU 分解求解线性方程组(带 permutation,可以 inplace 等版本),QR 分解(包括选取列的),SVD,Cholesky 分解,实对称矩阵的对角化分解(本征分解),Hermite 矩阵的对角化分解,实矩阵的 Hessenberg 分解,实矩阵对的 Hessenberg 分解,双对角化(bidiagonalization),Householder 变换,Householder 变换求解线性方程组,三对角阵,balancing(通过相似变换使得行列的范数相当)。

Eigensystems 求解特征值 gsl_eigen.h
这部分包括实对称矩阵的特征值、Hermite 矩阵的特征值,以及非对称矩阵的特征值(利用 Schur 分解)以及对应的广义特征值问题求解的函数。一般需要 alloc 一个 workspace,然后调用对应的函数计算特征值、特征向量,最后 free 掉 workspace。另外还提供了对应的函数用于同时整理特征值与特征向量。

Fast Fourier Transform 快速 Fourier 变换 gsl_fft_*.h
快速 Fourier 变换这里分成了对复数、实数(更困难一些,需要保证逆变换获得是实数,使用的也是 halfcomplex 表达系数)两种处理。而对于数据为 2 的幂次的可以直接用 Cooley-Tuckey 算法,不是的话另外有一套算法(需要预先分配 workspace)。每套算法提供 forward(计算 Fourier 变换),inverse(逆变换),backward(不带规范化常数的逆变换)和 transform(通过参数选择 forward 还是 backward)。

Numerical Integration 数值积分 gsl_integration.h
函数命名方式是 gsl_integration_*(),Q 表示 quadrature routine,N 和 A(表示是否自适应),G 和 W(一般积分和带权值函数的积分),S 和 P(容易消解的奇点或者提供特别困难的点),I(无穷积分),O(振荡积分),F(Fourier 积分),C(Cauchy 主值)。积分里面设置停止条件是设置相对误差或者绝对误差。

Random Number Generation 随机数生成器 gsl_rsg.h
首先需要 gsl_rng_alloc() 一个对应的类型,然后 gsl_rng_set() 设置 seed,gsl_rng_free() 释放。同时还可以通过环境变量 GSL_RNG_TYPE 和 GSL_RNG_SEED 以及函数 gsl_rng_env_setup() 获取,然后通过设定对应的生成器就可以利用 gsl_rng_uniform() 产生 [0, 1) 的均匀分布,gsl_rng_uniform_pos() 产生 (0, 1) 的均匀分布,以及 gsl_rng_uniform_int() 产生指定范围内的均匀整数分布。另外可以通过 gsl_rng_name() 获得该生成器的名称,gsl_rng_get() 返回一个在 gsl_rng_min() 和
gsl_rng_max() 之间的随机数。如果需要更细致的处理生成器,还提供了一些函数用于处理它的状态 IO。另有一章详细介绍各种分布下随机数的生成情况。

Quasi Random Sequences 拟随机序列 gsl_qrng.h
与前一章不同的是不需要初始 seed,调用结构和前一章类似。

Random Number Distribution 随机数分布 gsl_randist.h
这里包含了绝大多数常用分布,命名规则如下 gsl_ran_dist(_),这里 dist 是分布名称,如 gaussian 等,后如果没有 _ 表示产生随机数,如果 _pdf 是密度,分布函数用了两种形式,一般是 cdf_dist_P 和 cdf_dist_Q 以及对应的逆 Pinv 和 Qinv。一共有下面几种分布,gaussian、gaussian_tail、bivariate_gaussian、exponential、laplace、exppow、cauchy、rayleigh、rayleigh_tail、landau、levy、levy_skew、gamma、flat、lognormal、chisq、fdist、tdist、beta、logistic、pareto、dir_2d、weibull、gumbel1、gumbel2、dirichlet。对于离散分布,有限个取值可以用 gsl_ran_discrete_preproc() 将分布密度列(或者差一个 scale factor)转换成为一个 gsl_ran_discrete_t 类型的结构,并传递给 gsl_ran_discrete() 产生随机数,gsl_ran_discrete_pdf() 产生分布列,产生的结构可以用 gsl_ran_discrete_free() 释放。另外提供了 poisson、bernoulli、binomial、multinomial、negative_binomial、pascal、geometric、hypergeometric、logarithmic。除了分布函数,还可以把指定序列随机打乱 gsl_ran_shuffle()、随机选元素 gsl_ran_choose()、选择一个子集 gsl_ran_sample()。

Statistics 统计 gsl_stats.h
主要提供统计函数,如求均值 gsl_stats_mean(),子样方差(无偏) gsl_stats_variance()、子样方差(已知期望,有偏) gsl_stats_variance_m(),标准差两个版本 std 和 std_m,与期望平方和 tss 和 tss_m,另外两个是 variance_with_fixed_mean 和 sd_with_fixed_mean。绝对偏差 absdev 和 absdev_m,skew 用 skew、skew_m_sd,峰度 kurtosis 和 kurtosis_m_sd,自相关性 lag1_autocorrelation 和 lag1_autocorrelation_m,协方差 covariance 和 covariance_m,相关系数 correlation,另外有对应的带权值版本在前面加上 w 即可。另外也提供了最大最小以及对应 index 的函数,计算中位数以及分位数的函数。

Histograms 直方图 gsl_hostogram*.h
分一维和两维,差异不大,主要把一维的增加新的一个变量,命名在 histogram 后面加 2d 即可。大致使用的方法是,首先 gsl_histogram_alloc() 分配空间,然后 gsl_histogram_set_ranges 设置节点(或者用 gsl_histogram_set_ranges_uniform() 设置均匀的节点),最后 gsl_histogram_free()。另外还提供了复制 gsl_histogram_memcpy() 以及自身复制 gsl_histogram_clone() 的函数。可以通过 gsl_histogram_increment() 增加元素到计数,也可以 gsl_histogram_accumulate() 增加任意权值(计数器用的实数),可以获得某个 bin 的权值 gsl_histogram_get(),或者某个 bin 上下界 gsl_histogram_get_range(),整个 histogram 的上下界 gsl_histogram_min/max(),bin 的数目 gsl_histogram_bins(),而 gsl_histogram_reset() 将整个 histogram 清零。gsl_histogram_find() 返回某个值所在的 bin。另有 max/min_val/bin 返回最大值或者出现的 bin,还有利用这个 histogram 计算 mean、sigma(标准差)、sum。另外两个 histogram 可以用 gsl_histogram_equal_bins_p() 看看是否可以使用 add/sub/mul/div 等运算,shift 可以让所有值 + 常数,scale 是乘。还有一些 IO 的函数。可以用 gsl_histogram 来创建一个 gsl_histogram_pdf,这个就和前面讲的随机数一样用。

N-tuples N 元组 gsl_ntuple.h
非常简单的数据结构,用于把数据写入/读出文件,提供的基本操作有 gsl_ntuple_create() 创建一个空文件(截断已存在),gsl_ntuple_open() 打开已存在文件,或者 gsl_ntuple_write() 将 ntuple 写入文件,或者从文件中读入 ntuple 数据 gsl_ntuple_read(),最后需要 gsl_ntuple_close() 关闭。可以把一个 ntuple 数据读入喂给 histogram 进行统计,这主要使用 gsl_ntuple_project() 函数。

Monte Carlo Integration 蒙特卡罗积分 gsl_monte_*.h
实现的是最基本的三种积分方法,在 gsl_monte.h 里面声明了积分函数的基本形式 gsl_monte_function,在 gsl_monte_plain.h 提供的是最简单均匀采样积分方法,首先 gsl_monte_plain_alloc() 分配 workspace,gsl_monte_plain_init() 初始化,然后 gsl_monte_plain_integrate() 积分,最后 gsl_monte_plain_free() 释放 workspace。在 gsl_monte_miser.h 里面使用的分层蒙特卡罗积分,可以用 gsl_monte_miser_state 结构控制算法细节。而 gsl_monte_vegas.h 是使用 impartance sampling,gsl_monte_vegas_state 控制算法细节。复杂的 MCMC 等这里并没有实现。

Simulated Annealing 模拟退火 gsl_siman.h
只有一个函数 gsl_siman_solve(),提供优化函数等信息即可使用。

Ordinary Differential Equations 常微分方程 gsl_odeiv.h
主要使用 gsl_odeiv_system 结构,需要提供方程标准形式的函数和偏导(即 Jacobi 矩阵)。另外和算法相关的是 stepping function,如 Runge-Kutta 方法等,也有自适应版本的,这种函数的目的是为了计算指定一个 step 下函数值。GSL 还提供了计算一个区间内函数变化(若干 step)的函数(evolve)。但是由于对常微分方程数值解不很了解,这里就略去吧。

Interpolation 插值 gsl_spline.h、gsl_interp.h
提供了三次样条和 Akima 样条。比较 low-level 的函数为用户提供了非常细致的控制,通过 gsl_interp_alloc() 分配需要的空间,选择适当的算法,gsl_interp_init() 初始化节点,最后 gsl_interp_free() 释放。为了搜索某个位置(以便计算函数值)可以用 gsl_interp_bsearch(),也可以使用 gsl_interp_accel 对象(先 init,然后 find 和 free)。另外提供了最常用的函数值、一阶导、二阶导和积分以及对应使用 gsl_interp_accel 的接口。high-level 的函数主要在 gsl_spline.h 里面提供。和 gsl_interp_* 系列相似。

Numerical Difference 差分 gsl_deriv.h
提供了中心差分 gsl_derive_central()、前向 gsl_deriv_forward()、后向 gsl_deriv_backward()。

Chebyshev Approximation 车比雪夫逼近 gsl_chebyshev.h
提供了 [-1, 1] 上一组正交多项式,这对应的是 1/sqrt(1-x^2) 为权的函数空间。首先用 gsl_cheb_alloc() 分配空间产生 gsl_cheb_series 结构,然后 gsl_cheb_init(),最后 gsl_cheb_free()。提供了计算函数值、函数值误差,导函数和积分。

Series Acceleration 级数加速 gsl_sum.h
提供了一个 Levin u-transform 的东西,没听说过。其意义在于减少求和项,提高计算精度。使用方式就是通过 gsl_sum_levin_u_alloc() 分配 workspace,继而通过 gsl_sum_levin_u_accel() 分配,最后 gsl_sum_levin_free()。如果不需要估计误差,则可以更快。

Wavelet Transform 小波变换 gsl_wavelet*.h
与 FFT 类似,但是没有 backward 类型,分一维和二维,有 daubechies、haar 和 bspline。

Discrete Hankel Transform 离散汉克尔变换 gsl_dht.h
与 FFT 类似,但是是对极坐标的,调用方式和 FFT 类似。

One-dimensional Root Finding 一维函数求零点 gsl_roots.h
有两种方式(基于搜索 gsl_root_fsolver 和基于导数 gsl_root_fdfsolver)。首先选取合适的 solver,命名方式都是 gsl_root_*solver_type,然后 alloc。之后可以用 gsl_root_*solver_set() 设定初始态,开始迭代使用 gsl_root_*solver_iterate(),也可以直接用 gsl_root_*solver_root() 求出根。另可以 gsl_root_fsolver_x_upper() 和 gsl_root_fsolver_x_lower() 返回控制根的区间。通过 gsl_root_test_*() 可以测试相对误差、残差。提供的算法有 bisection、falsepos 和 brent,利用梯度的有 newton、secant、steffenson。

One-dimensional Minimization 一维函数求极小 gsl_min.h
最小化在某种意义上就是求导函数的零点。因此调用方法和前一章极为类似。算法有 goldensection 和 brent。

Multi-dimensional Root Finding 多维函数求零点 gsl_multiroots.h
类似。算法有 hybridsj,hybridj,newton,gnewton。不用梯度的算法有 hybrids,hybrid,dnewton,broyden。

Multi-dimensional Minimization 多维函数求极小 gsl_multimin.h
类似。算法有 conjugate_fr、conjugate_pr、bfgs、bfgs2、steepest_descent、nmsimplex。

Least Square Fitting 最小二乘拟合 gsl_fit.h
分单变量和多变量。gsl_fit_linear() 和 gsl_fit_wlinear() 分别是线性和加权线性问题的单变量拟合(即线型回归),另外 gsl_fit_linear_est() 还估计误差。多元情形为 gsl_fit_mul()、gsl_fit_wmul() 与 gsl_fit_mul_linear()。对广义的 LSF 问题,需要使用 gsl_multifit_linear_alloc() 分配 workspace,最后释放,类似的函数有 gsl_multifit_linear 和 weighted 版本,另有 _svd 版本,使用 SVD 计算结果。

Nonlinear Least Square Fitting 非线性最小二乘拟合 gsl_multifit_nlin.h
与多维函数最小化类似。

Basic Splines 基础样条 gsl_bspline.h
先 gsl_bspline_alloc() 产生 workspace,然后 gsl_bspline_knots() 或者 gsl_bspline_knots_uniform() 设置节点,gsl_bspline_eval() 计算函数值,最后 gsl_bspline_free() 释放空间。

Physical Constants 物理常数 gsl_const_mksa.h
各种可能用到的物理常数,命名一般为 GSL_CONST_MKSA_*。

IEEE Floating Point Arithmetic 浮点算术 gsl_ieee_utils.h
提供了输出 float 和 double 的 gsl_ieee_printf_*,另外可以用 gsl_ieee_env_setup() 设置对应的计算环境。

相关程序:
  • GSL 的 C++ wrapper:GSLwrap
  • 一个用 GSL 写的 PCA 程序,和 mex 一起工作。

2008年7月29日星期二

bc

bc 是命令行下一个任意精度的计算器语言(可不是那个 bc 哦),包含有以下内容:
/usr/bin/bc
/usr/share/doc/bc/README
/usr/share/doc/bc/AUTHORS
/usr/share/doc/bc/copyright
/usr/share/doc/bc/examples/ckbook.b
/usr/share/doc/bc/examples/pi.b
/usr/share/doc/bc/examples/primes.b
/usr/share/doc/bc/examples/twins.b
/usr/share/doc/bc/changelog.gz
/usr/share/doc/bc/NEWS.gz
/usr/share/doc/bc/changelog.Debian.gz
/usr/share/menu/bc
/usr/share/man/man1
/usr/share/man/man1/bc.1.gz
结构非常的简单。既然说是一种语言,那么就对应有它的语法。bc 本身提供了一个交互式界面(-i 或者默认的情况),另外也允许把一些命令写入文件执行(作为命令参数)。Debian 带的 bc 是扩展之后的版本,如果希望使用 POSIX 标准下的 bc 可以用 -s,另外可以用 -l 读入数学库调用里面的函数。

bc 里面的数字有两个属性,一个是 length(表达该数字使用的位数),一个是 scale(该数字使用小数个数)。变量名命名规则和 C 语言类似,有几个重要的变量控制着 bc 的行为,比如 scale 表示输出的时候显示的小数点位数,ibase 和 obase 指定输入输出的进制(默认都是 10 进制),last 记录了上次计算结果。注释使用 /* 和 */ 对或者单行注释 #。使用的运算符和 C 类似,如四则运算、赋值、自增自减、逻辑运算等,另外控制结构比如 if、while、for、流程控制命令 break、continue、return 等也完全一致。

bc 提供了几个常用的表达,如 length()、scale() 求对应的长度、小数点后位数,read() 读入用户输入的数据,sqrt() 求平方根。print 和 printf 类似。halt 表示退出 bc。limits 显示系统的一些限制,quit 是退出 bc。另外 bc 允许自定义函数,格式是 define function-name( parameter list ) {},在函数体里面有 auto 定义的局部变量。函数可以为 void 类型,此时不返回值。

使用数学库,有正弦 s()、余弦 c()、反正切 a()、自然对数 l()、指数函数 e() 和 n 阶 Bessel 函数 j( n, x) 可以用。

2008年7月28日星期一

lftp

lftp 作为 Linux 下最常用的 ftp client 之一,一直是我见到的最好的命令行工具之一,比起 GUI 来说它有自己的很多优点。这是该包内东西:
/usr/bin/lftp
/usr/bin/lftpget
/usr/share/man/man1/lftp.1.gz
/usr/share/man/man1/lftpget.1.gz
/usr/share/lftp/import-ncftp
/usr/share/lftp/import-netscape
/usr/share/lftp/verify-file
/usr/share/lftp/convert-netscape-cookies
/usr/share/doc/lftp/BUGS
/usr/share/doc/lftp/FAQ
/usr/share/doc/lftp/README.debug-levels
/usr/share/doc/lftp/README.modules
/usr/share/doc/lftp/TODO
/usr/share/doc/lftp/copyright
/usr/share/doc/lftp/NEWS.gz
/usr/share/doc/lftp/README.gz
/usr/share/doc/lftp/changelog.Debian.gz
/usr/share/doc/lftp/changelog.gz
/etc/lftp.conf
我们看到有两个工具 lftp 和 lftpget,后者本身是一个 shell script 用来调用 lftp 下载。因此我们主要介绍 lftp 的用法。lftp 一般作为一个交互式程序来运行。它自己会屏蔽 SIGHANGUP 这类信号,如果在还有下载任务时退出或者出现意外断线什么的,这可以保证该进程不会退出。lftp 也不仅仅支持 ftp 协议,它还可以从 ftps、http、https、hftp、fish、sftp 和 file 这些协议下载文件。lftp 提供的交互环境和 shell 类似,下面介绍一些常用的命令:
  • !shell command 执行一个 shell 里面的命令
  • anon 使用匿名用户。
  • at time -- command 在指定时间执行命令,比如下载等等。
  • bookmark add name loc 增加一个地址到书签,bookmark del name 删掉一个书签,bookmark edit 编辑书签文件,bookmark list 列出书签,bookmark import 用于导入书签。
  • cache 用于管理 lftp 的缓存,如 cache stat 列出统计信息,cache on/off 打开关闭 cache,cache flush 将 cache 写入硬盘,cache size 设置 cache 大小,cache expire 设置移除 cache 时间。
  • cat 将远程文件内容输出到 stdout。
  • cd 切换远程路径,lcd 切换本地路径
  • chmod 改变远程文件属性。
  • close 关闭连接。
  • ls 和 cls 都是列出文件信息,但是前者是依照服务器反馈,后者会依照自己的格式。另外 nlist 仅仅列出文件名,不列其他的信息。
  • command 忽略 alias 执行命令。
  • debug 改变 debug level 并输出到指定文件。
  • echo,man page 里面居然写 guess what it does。
  • eval 一般都是用来执行某个命令,可以提供指定格式(-f)
  • exit,可加 bg 表示退出后强制在后台下载,top 是把登录 shell 也退出了,kill 是杀死未完成任务。
  • fg 就是 wait 的 alias,表示在前台等候前一个命令终止。
  • find 和 ls -R 类似,但是如果服务器不支持 ls -R 可以用 find。
  • get 和 put 是 ftp 里面的基本命令,用于下载或者上传单一一个文件。
  • glob 将一个 pattern 转换后传给一个命令,基本用法是 glob command pattern
  • jobs 列出现在执行的任务。
  • kill 杀死指定任务,或者 kill all 杀死所有的。
  • pwd 和 lpwd 显示远程和本地的当前工作目录。
  • mirror 用于同步远程和本地的文件/目录,可以从远程同步到本地,也可以从本地同步到远程(-R),可以用 -i 指定下载的文件或者 -x 排除某些文件。
  • module 加载模块。
  • mkdir 创建目录。
  • more 类似 cat 根据 PAGER 设定分页。
  • mput 和 mget 使用 wildcard 上传或者下载文件。
  • mrm 实际上是 glob rm 的 alias。
  • mv 重命名
  • open 连接某个站点。
  • pget 使用几个连接下载文件。
  • quote 直接发送协议里面的命令,如 http 请求等
  • reget 和 get -c 一样,reput 和 put -c 一样;rels、renlist 重新生成 cache。
  • rm 删除文件。rmdir 删除目录。
  • repeat 可以用于反复执行某个命令。
  • set 设置变量。
  • scache 列出 cached 的 session 或者切换 session。
  • sleep 指定时间并退出。
  • site 执行 site_cmd。
  • source 执行一个文件里面的命令。
  • user 设定登录用户和密码。
  • version 获取版本号。
  • zcat 和 zmore 是调用 zcat 和 zmore 显示压缩文件内容。

下面看看 lftp 的配置,一般系统配置文件放在 /etc/lftp.conf,用户自己的放在 ~/.lftprc 或者 ~/.lftp/rc。一般里面用 alias 指定一些常用的命令,set 设定某些变量值,debug 打开调试状态等。set -a 会显示所有的设置,这里仅仅写一些常用的变量,其他的请参考 man page:
  • bmk:save-passwords (boolean) 是否保存站点的登录密码。
  • cmd:move-background (boolean) 默认状态下退出是否进入后台。
  • cache:size (number) 设置 cache 大小。
  • dns:order (list of protocol names) 设置查询 DNS 顺序,默认是先 inet6 后 inet。
  • file:charset (string) 存盘文件名编码方式。
  • ftp:anon-pass 匿名用户的密码
  • ftp:passive-mode (boolean) 所谓 passive mode 就是客户端打开端口反向连接 server 传输。
  • ftp:port-range (from-to) 设置打开 PASV 模式使用的端口范围。
  • http:proxy 设置 http 的代理。
  • net:limit-rate (bytes per second) 限制下载速度。
  • net:reconnect-interval-max (seconds) 重连时间。
  • pget:default-n (number) 使用 pget 分割的块数。

tasksel

看起来很简单的工具,里面的内容:
/usr/bin/tasksel
/usr/lib/tasksel/tasksel-debconf
/usr/lib/tasksel/packages/list
/usr/lib/tasksel/tests/debconf
/usr/lib/tasksel/tests/new-install
/usr/lib/tasksel/tests/lang
/usr/share/doc/tasksel/README.gz
/usr/share/doc/tasksel/TODO
/usr/share/doc/tasksel/copyright
/usr/share/doc/tasksel/changelog.gz
/usr/share/man/man8/tasksel.8.gz
/usr/share/menu/tasksel
只要 tasksel --list-tasks 就可以看到一些设定好的 task,好像就是装 Debian 的几个基本的 task,不知道可以自定义些复杂的 task 不?如果需要某项可以 tasksel install/remove 安装或者卸载。

2008年7月18日星期五

manpages

一直不知道 manpages 里面是啥,发现基本全是文档,这里从里面比较有意思的地方节选一些出来。这是 manpages 的主页

sync
将文件同步到磁盘。比如 U 盘拔掉之前,sync 一下 umount 就结束了,否则 umount 会调用 sync。

tzselect
选择 time zone,根据用户输入信息输出一个可以设置为 TZ 变量的值。

intro (man 1)
介绍 user commands 和工具,如文件管理、shells、编译器、浏览器、文件图片浏览器、编辑器等。多数程序成功返回 0,失败返回非 0(一般是正数)。
intro (man 2)
介绍 system call,不过多数 system call 都用 C 或者其他的 lib wrapper 调用。多数成功返回 0,不成功返回负值。
intro (man 3)
库函数手册,比如 libc、libm 等。
intro (man 4)
介绍特殊文件,主要是 /dev/ 里面的。
intro (man 5)
介绍文件格式和协议,乃至一些 C 的结构。
intro (man 6)
介绍游戏,系统里面一些搞笑的小程序。
intro (man 7)
介绍习惯、字符集、标准文件系统布局。
intro (man 8)
多仅被超级用户使用的命令,管理命令,硬件相关的命令等。

uri, url, urn
介绍 Uniform Resource Identifier(包括 URLocation 和 URName)。基本格式就是 scheme://path 这种了。常见的有 http、ftp、gopher、mailto、news、telnet、file、man、info、whatis、ldap、wais 等。甚至还有 eMule 等的 scheme。

iso_(-)8859-(_)1...iso_8859-16, latin1-2
是讲述 iso 8859-9 编码。

ipv6, PF_INET6
讲述对应 socket 编程在 C 的结构体。

mq_overview
讲述如何使用 POSIX 消息队列,这是和 SVID 不同的一个,通过她可以让进程之间互相通信,几个重要函数是 mq_open 打开一个队列获得 message queue discriptor,通过 mq_send 和 mq_receive 收发信息,最后 mq_close 关闭该队列(另外还有一系列函数)。通信双方通过 /name 确定队列。连接时 -rt。

mailaddr
关于电子邮件地址的说明。

x25, PF_X25
关于 X.25 协议的 socket 结构。

feature_test_macros, ftm
为写出某些特点的程序写的测试 macros,见 /usr/include/features.h,比如要求是标准 ANSI C 的环境,可以用宏 __STRICT_ANSI__ 来测试,另外可以测试是否满足 SVID 等扩展版本,这在 GNU libc 里面有一些例子,因为 libc 允许根据这些宏判定某些函数是否被是用,通过这些测试可以避免不适当的引入某些函数。

regex, re_format
讲述的 POSIX.2 的正则表达式的基础语法。

spufs
是 PowerPC 上的文件系统的挂载命令。

undocumented
未收入 man page 的说明。

raw, SOCK_RAW
见前

LDP
关于 The Linux Documentation Project 的介绍,有官网 http://tldp.org

bootparam
如何设定 kernel 在 boot 时候的参数:一个 option 一共只能给 10 个参数,格式为 name=val1,val2...,如果 name 是一些已知的名字如 init、root 等会调用对应的 *_setup() 进行配置,否则当作环境变量进行处理。下面是一些常用的名字:init 指定启动后执行的第一个进程位置,一般来说会尝试 /sbin/init、/etc/init、/bin/init 和 /bin/sh,如果全部失败了就会导致 kernel panic;nfsaddrs 指定 NFS 的地址,用于网络启动;nfsroot 指定挂载 NFS 分区为网络启动的 root;no387 关闭对 math coprocessor 的支持;no-hlt 关闭对 HALT 指令的支持;root 指定挂载为 / 的设备;ro/rw 让 / 为只读或者可读可写;reserve=iobase,extent[,iobase,extent] 保留某些 I/O 端口不做 probe;mem 设定内存大小;panic=N 表示发生 kernel panic 后 N 秒重启;reboot=[warm|cold][,[bios|hard]] 设定 reboot 方式;nosmp 取消 SMP,maxcpus=N 设定最多使用的 CPU 个数;debug 打开调试信息;profile=N 打开 kernel profile 功能;swap=N1,N2,N3,N4,N5,N6,N7,N8 设定 swap 相关参数;buff=N1,N2,N3,N4,N5,N6 设定 buff 信息;load_ramdisk=N 设置是否使用 ramdisk;prompt_ramdisk 是否从软盘读入 ramdisk;ramdisk_size=N 设定 ramdisk 大小(单位 Kb);ramdisk_start=N 设定 ramdisk 的起始位置(在软盘上存在 kernel 和 ramdisk 的时候使用);noinitrd 不使用 initrd。另外还可以设定一些 SCSI 设备的参数。

missing
丢失的文档。

boot
讲述 boot 的过程。首先是机器上电,BIOS 自检,从 CMOS(其实叫 NVRAM 更好)读取配置,然后从 boot device 读入 os loader,将控制权交给 os loader。PC 上面一般放在 MBR 里面,由于 MBR 仅有 512 字节,且还含有 64 字节的分区表信息,所以 os loader 往往将自身的一部分放在 MBR 然后引导另一部分,同时根据引导 kernel 的参数将控制权交给 kernel。如果有 initrd 则会将其转换成为 ramdisk 并挂载成为临时的 /,然后执行 /linuxrc,最后挂载了 / 之后就可以执行 init 进程了。init 根据 /etc/inittab 决定运行级别,一些服务放在 /etc/rc?.d/ 里面,其实是到 /etc/init.d/ 里面脚本的连接。

tcp
讲述 tcp 的 C 接口。

netlink, PF_NETLINK, rtnetlink, NETLINK_ROUTE
讲述 PF_NETLINK 编程。

posixoptions
介绍了 POSIX 标准下的函数接口,一般可以用宏在编译时检测,也可以用 sysconf()、pathconf()、fpathconf() 和 confstr() 来检测。

netdevice
设定 interface 的 C 接口。

futek
关于快速用户空间互斥锁。

man(7)
其实是说如何写 man page,通过 groff 输出成为 ASCII 或者 PS。

packet, PF_PACKET
如何产生一个 PF_PACKET 的 C 接口。

mdoc
man page 的另外一种格式,也是通过 groff 转换的。

arp
介绍 arp 命令管理本地 MAC-IP 转换的表,如 arp -n 列出现在的 ARP 表,-d 删除,-s 添加表项。

ip(7)
介绍 IP 的 C 接口。

signal
介绍常用的信号以及 POSIX 信号。

socket
介绍 socket 的 C 接口。

glob
介绍 bash 通过 wildcard 匹配的规则。这个不是 RE,比较简单。

charsets
介绍最常用的字符集、编码方式等。

ascii
介绍 ascii 编码。

standards
介绍 Unix/Linux 里面各种 C 编程的标准。

hier
介绍 Linux 目录树。

koi8-r
是俄文常用编码。

locale(7)
介绍的是 locale 的 C 接口。

pthreads
介绍的是 POSIX threads 的 C 接口。

pty, pts, ptmx, tty(4), tty_ctl
介绍 pseudo-terminal 两种类型(Unix 98 和 BSD,前者使用较多)以及使用方式。pts 讲述 Unix 98 的 master 和 slave 关系,如何通过 C 接口实现。tty 是讲述 /dev/tty 设备。tty_ctl 是 tty 的 ioctl。

epoll
对 edge-triggered 或者 level-triggered 的 IO 事件响应的一种实现,和 poll 类似。

capabilities
这是对原有线程访问模型的一个增补(原来只要 UID 为 0 就无敌了),在 2.6.14 以后的内核中出现的,以后内核对这部分进行检查、并提供了对应的系统调用更改这些,问题是现在还没有获得文件系统的支持。

fifo
介绍 FIFO(这里是 named pipe) 的使用。

symlink
讲述符号连接操作的习惯相关的 C 函数。

complex
讲述 GNU libc 里面 complex.h。


time(7)
讲述各种可用的时钟。

icmp, IPPROTO_ICMP
讲述 ICMP 协议。

termio
是驱动 terminal 的一些东西,已经 obsolete,被 termios 代替。

suffixes
常见“扩展名”

hostname(7)
讲 hostname 解析。

path_resolution
讲述 Linux 如何解析一个路径名称。

operator
C 语言使用 operator 列表及优先级。

unicode
讲述 unicode。

sem_overview
讲述 POSIX semaphore(用于同步)。

ddp
Linux 下 AppleTalk 协议的 C 实现。

unix, PF_LOCAL, AF_LOCAL, PF_UNIX
讲述 unix socket(PF_UNIX)。

man-pages
写 man page 的惯例。

units
介绍计算机上常用的关于大小的前缀,如 kb mb gb 等等。

environ
讲述 C 程序传递 argc、argv 之外的 environ。

credentials
讲述用户、进程的标识。

inotify
讲述监督文件、目录等文件系统事件的 C 接口程序。

utf-8, utf8
讲述 utf-8 编码。

udp
讲述 udp 协议的 C 接口。

shm_overview
讲述 POSIX shared memory(共享内存)。

svipc
讲述的是 SVID 下 IPC 实现机理。

pipe
讲述的是 pipe 和 FIFO 的使用。

mem, kmem, port
介绍 /dev/mem、/dev/kmem 和 /dev/port,mem 一般是物理内存,而 kmem 是内核虚拟内存,port 用于访问物理端口。

random, urandom
介绍 /dev/random 和 /dev/urandom,它们维护一个 entropy pool,根据这个产生随机序列,前者在 entropy 足够高时返回,否则 block,而后者立即返回,因此需要比较高质量的随机序列时应多用 /dev/random。一般用 dd 从这些设备获得需要的随机数。

console_ioctl
设定 console 的 ioctl 参数。

ttyS, ttys
讲述 /dev/ttyS 设备(串口)。

hd(4)
讲述 /dev/hda 到 /dev/hdd 这四个 IDE 硬盘设备。

mouse(4)
讲述 ps/2 鼠标各个 pin 的作用,相关的协议。

st
讲述 SCSI 磁带的 C 语言接口。

full
讲述 /dev/full 设备,如果写可以触发 disk full,读只能读出 \0。

dsp56k
是 Motorola dsp56k 设备的 ioctl。

lp(4)
是 line printer device 的 ioctl。

sk98lin
是讲述 Marvell 和 SysKonnect G 以太网网络适配器的模块。

sd
讲述 SCSI 设备的 ioctl。

initrd
是 /dev/initrd 设备,对应的是 boot loader 加载的 initrd 的 ram disk。

wavelan
是 NCR、AT&T、Lucent WaveLAN ISA 和 Digital (DEC) RoamAbout DS 无线网卡适配器的模块说明。

ram
是 /dev/ram 设备。

rtc
是 real-time clock 的 C 接口和 ioctl。

null, zero
讲述 /dev/null 和 /dev/zero 设备。

console_codes
介绍 Linux console 里面的控制字符等。

vcs 和 vcsa
是虚拟 console 内存,对应 /dev/vcs*。

hosts.equiv
介绍 /etc/hosts.equiv 文件,这是控制 r* 系列命令的登录权限的文件。

mailname
介绍 /etc/mailname 文件,写的是系统对外可见的邮件名。

motd
介绍 /etc/motd,就是登录后显示每日的消息。

tzfile
介绍 tzfile.h 里面关于时区的信息。

securetty
介绍 /etc/securetty,也就是系统认为是安全的 tty,这可以限制 root 通过不安全的途径登录。

rpc
介绍 /etc/rpc,也就是 remote procedure call(远程过程调用),里面记录了 rpc 号以及对应的服务。

elf
是介绍 ELF 文件格式的 C 接口(elf.h)。

shells
介绍 /etc/shells 文件,里面是所有合法的 shells,包括路径等,这使得 chsh 能安全的工作。

host.conf
配置如何解析主机名,即 resolver library。

proc
介绍 proc 文件系统。

resolv.conf, resolver
配置 DNS 的文件,但是现在多用动态方式生成。

group
组信息,介绍 /etc/group 文件。

acct
介绍 sys/acct.h 的用法,用于进程 accounting(内核会在进程结束后写该进程的一些相关信息到某文件)。

locale(5)
解释 locale 是怎么用的(不是解释这个命令)。

nsswitch.conf
用来查询用户帐号信息,如选择 /etc/passwd、nis 或者别的什么。

services
讲述文件 /etc/services,这在 C 程序里面可以用一些对应的命令获得查询。

slabinfo
讲述 /proc/slabinfo,这个文件是 kernel 管理的 slab 的统计信息(常用的一些如 buffer heads、inode 等)。

charmap
charmap 就是用于定义哪些字符属于某个 charset 的文件。

hosts
讲述/ etc/hosts 文件。

utmp, utmpx, wtmp
记录用户登录信息的文件,也就是 /var/run/utmp 的用法。

nologin
介绍 /etc/nologin 拒绝用户登录的文件。

core
介绍 core dump 信息怎么用于调试。

filesystems, fs
介绍常用的 file systems。

termcap
介绍 /etc/termcap,描述了每个 term 的特性。

dir_colors
通常 ls 命令依据 LS_COLOR 设定颜色,这通过 dircolors 命令设定。用户可以根据自己的爱好定义。

issue
讲述 /etc/issue,即在出现提示符前出现的文件。

networks
讲述 /etc/networks,即网络名和对应地址的映射。

protocols
讲述 /etc/protocols 文件,即一些协议对应的网络端口以及别名。

motd.tail
在 debian 里面这是 bootmiscs.sh 生成 motd 的源程序,应该修改它获得永久的效果。

ld-linux, ld-linux-so
这是 Linux 的动态库连接程序,一方面会把需要的 so 文件载入内存,另一方面修改进程相关内容完成动态连接。

相关程序:
sync 来自 coreutils,在 man 1 里面也有。
tzselect 来自 libc6,在 man 1 里面也有。

2008年7月17日星期四

e2fsprogs

这是关于 EXT2/3 文件系统的程序集合,
/etc/mke2fs.conf
/sbin
/sbin/resize2fs
/sbin/fsck.ext2
/sbin/mkfs.ext2
/sbin/e2fsck
/sbin/findfs
/sbin/fsck.ext4dev
/sbin/blkid
/sbin/logsave
/sbin/fsck.ext3
/sbin/mke2fs
/sbin/e2image
/sbin/tune2fs
/sbin/e2undo
/sbin/mkfs.ext4dev
/sbin/e2label
/sbin/mkfs.ext3
/sbin/mkfs.ext4
/sbin/dumpe2fs
/sbin/fsck
/sbin/fsck.ext4
/sbin/debugfs
/sbin/badblocks
/usr/bin/lsattr
/usr/bin/chattr
/usr/share/e2fsprogs
/usr/share/e2fsprogs/initrd.ext3-add-journal
/usr/sbin
/usr/sbin/filefrag
/usr/sbin/mklost+found
/usr/lib
/usr/lib/e2initrd_helper
略去其中其他的帮助文档。以下是各个命令的功能介绍:
  • resize2fs 是用于调整 EXT2/3 文件系统的大小,离线的设备可以调整,如果已经 mount 的话,ext3 在 2.6 的内核里面已经支持在线调整了。值得注意的是,该命令并不调整分区大小,因此一般需要通过 fdisk 将后面分区删除,然后才能 resize2fs dev size;缩小分区时是 resize2fs 然后 fdisk。
  • fsck.ext2 是 ext2/3 文件系统查错程序,和 e2fsck 一样功能。。
  • mkfs.ext2 创建 ext2/3 文件系统,和 mk2efs 一样功能。
  • findfs 通过 LABEL 或者 UUID 获得设备名。
  • fsck.ext4dev 和 mkfs.ext4dev 是 ext4 文件系统的工具,只是现在尚未完全完成。
  • blkid 用于搜索显示 block device 相关的信息,如是否为 swap,UUID 和 LABEL 等。如
    $ sudo blkid /dev/sda1
    /dev/sda1: UUID="6E0C10D80C109D61" TYPE="ntfs"
  • logsave 可以将一个命令的输出写到指定的文件中,其不同之处在于,如果该文件不可写,则写入在内存直到该文件可写;比如启动时内核输出信息一般应计入 /var/log,但是 /var 分区可能尚未挂载。
  • fsck.ext3 和 mkfs.ext3 是 ext3 文件系统的查错、创建程序,本质上和 ext2 版本一样。
  • e2image 用于从一个 ext2/3 分区中提取关键性信息产生一个 image 文件,该文件有助于分析损坏的文件系统,一般是提供给 dumpfs 和 debugfs 命令(通过 -i 选项)。
  • tune2fs 是用来调整 ext2/3 文件系统的一些特定功能,这些功能多数在 mkfs 的时候可以指定,这里详细的介绍一下:-c 最大挂载次数(满足后会 fsck,0 或者 -1 则忽略),-C 设定挂载次数计数器,-e 出错处理方式(如 continue,remount-ro 或者 panic),-E 设置扩展选项(主要是 RAID 和 ext4 的一些属性),-f 强制执行命令即便出错,-g 设定用户组可以使用保留的空间,-i 设定文件系统检查间隔(即使没达到挂载次数的限制),-j 打开 journal(即 ext3 文件系统),-J 设定 journal 的选项(size 指定大小,device 设定外部保存 journal 的设备),-l 列出 super block,-L 设定 LABEL,-m 设定保留空间的百分比(默认 5),-M 设定最后被挂载的目录,-o 另外一些挂载选项(debug 调试功能打开,bsdgroups 使用 bsd 的行为,user_xattr 使用用户扩展属性,acl 使用 POSIX acl,uid16 使用老式 16bit 的 uid,journal_data 不仅仅对 meta data 做日志也对数据本身作,journal_data_ordered 和 journal_data_writeback 是设定 data 还是 metadata 首先写入日志),-O 设定一些文件系统的特性(large_file 允许大于 2 Gb 文件,dir_index 使用 B-tree 加速,filetype 储存文件类型信息,has_journal 和前面 -j 一样,sparse_super 限制备份 super block 的数目,resize_inode 保留一定的空间以便 inode 增加,uninit_bg 打开可减少 fsck 时间;这部分应用后应该 fsck 使得文件系统保持一致性),-r 保留 super block 数目,-T 上次 fsck 时间,-u 设定使用保留空间的用户,-U 设定 UUID。
  • e2undo 将重放 ext2/3/4 文件系统的 undo log。
  • e2label 设定 LABEL。
  • dumpe2fs 将会把 super block 上的信息 dump 到 stdin。
  • fsck 文件系统检查一般性的命令。
  • debugfs 是 ext2 文件系统交互式除错工具,啊,甚用。
  • badblocks 对指定的设备检查坏掉的块。
  • lsattr 和 chattr 是对 ext2/3/4 文件系统特有的属性进行查阅和更变。chattr 和 chmod 类似,可以用 +-= 设置对应的属性位。A 在被访问是不更改 atime,a 进允许 append(只有 root 才可能设置),c 自动被压缩,D 对目录表示写入改动立即被同步(dirsync),d 表示不被 dump 等程序备份,E 表明出现了压缩错误,I 表明使用了 hashed tree 加速索引,i 说明该文件不能被任何形式的更改,j 和前面 journal_data* 类似,s 表示会进行安全删除(先清 0),S 对文件表示写入等操作立即同步,T 对目录表示是?Orlov block allocator,完全谬听说过,t 表明该文件不会产生占据半个 block 与其他文件共享的碎片,u 表明删除后文件内容不会丢失,X、Z 都是实验性和压缩文件相关的属性。
  • filefrag 报告某指定文件碎片情况。
  • mklost+found 建立 lost+found 目录,并预留空间。

2008年7月15日星期二

x11-utils

该包内含有:
/usr/share/doc/x11-utils/copyright
/usr/share/doc/x11-utils/changelog.gz
/usr/share/man/man1/listres.1.gz
/usr/share/man/man1/luit.1.gz
/usr/share/man/man1/viewres.1.gz
/usr/share/man/man1/xdpyinfo.1.gz
/usr/share/man/man1/xdriinfo.1.gz
/usr/share/man/man1/xev.1.gz
/usr/share/man/man1/xfd.1.gz
/usr/share/man/man1/xfontsel.1.gz
/usr/share/man/man1/xkill.1.gz
/usr/share/man/man1/xlsclients.1.gz
/usr/share/man/man1/xlsfonts.1.gz
/usr/share/man/man1/xmessage.1.gz
/usr/share/man/man1/xprop.1.gz
/usr/share/man/man1/xvinfo.1.gz
/usr/share/man/man1/appres.1.gz
/usr/share/man/man1/editres.1.gz
/usr/share/man/man1/xlsatoms.1.gz
/usr/share/man/man1/xwininfo.1.gz
/usr/share/menu/x11-utils
/usr/bin/appres
/usr/bin/editres
/usr/bin/listres
/usr/bin/luit
/usr/bin/viewres
/usr/bin/xdpyinfo
/usr/bin/xdriinfo
/usr/bin/xev
/usr/bin/xfd
/usr/bin/xfontsel
/usr/bin/xkill
/usr/bin/xlsatoms
/usr/bin/xlsclients
/usr/bin/xlsfonts
/usr/bin/xmessage
/usr/bin/xprop
/usr/bin/xvinfo
/usr/bin/xwininfo
/etc/X11/app-defaults
/etc/X11/app-defaults/Editres
/etc/X11/app-defaults/Editres-color
/etc/X11/app-defaults/Viewres
/etc/X11/app-defaults/Xfd
/etc/X11/app-defaults/XFontSel
/etc/X11/app-defaults/Xmessage
/etc/X11/app-defaults/Xmessage-color
下面逐一介绍,
  • appres、editres、listres 和 viewres 是处理 X resource 的工具,appres 可以显示某一个程序或者子项目的相关 resource,listres 显示所有 widget 的 resource,editres 和 viewres 是显示 resource 的 GUI。
  • luit 被设计为任意程序与一个 utf-8 虚拟终端交互的 filter,已经不大用了,现在鼓励直接让程序生成 utf-8。
  • xdpyinfo 显示 X server 的信息,如使用了什么 extensions,分辨率之类的。
  • xdriinfo 显示 DRI 信息,不知道为啥 NVIDIA 的显卡上面都说 libGL 太老了 @@...
  • xev 可以为指定的窗口(-id)或者创建一个新窗口显示对应接受的 events,多用于调试 GUI。
  • xfd 显示某一个字体所有字符,可用 -fn 指定(X core font)字体名或者 -fa 指定 Xft 字体名。
  • xfontsel 是一个显示各个字体样例的程序。
  • xkill 是杀掉 X clients 的一个程序,需要用 -id 指定 resource,或者不指定会让用户用鼠标点击。
  • xlsatoms 列出 X server 端 atom,似乎跟 X server 有关系,但是不知道是些啥 -,-b
  • xlsclients 列出连在某个 X server 上的 X clients。
  • xlsfonts 列出所有 X core fonts。
  • xmessage 设计的目的和 echo 类似,显示在屏幕上一个窗口,可以自定义文字,按钮和返回值。
  • xprop 显示或更改指定 X client 的 X server 属性。
  • xvinfo 显示 X-video extension 的信息。
  • xwininfo 显示对应 window 的信息。

这里就一些细节进一步讨论。

2008年7月7日星期一

x11-xserver-utils

这是一组 X 里有用的命令集合,比较底层,包括
/usr/share/doc/x11-xserver-utils/copyright
/usr/share/doc/x11-xserver-utils/changelog.gz
/usr/share/man/man1/sessreg.1.gz
/usr/share/man/man1/showrgb.1.gz
/usr/share/man/man1/xcmsdb.1.gz
/usr/share/man/man1/xhost.1.gz
/usr/share/man/man1/xmodmap.1.gz
/usr/share/man/man1/xrandr.1.gz
/usr/share/man/man1/xrdb.1.gz
/usr/share/man/man1/xset.1.gz
/usr/share/man/man1/xsetmode.1.gz
/usr/share/man/man1/xsetpointer.1.gz
/usr/share/man/man1/xsetroot.1.gz
/usr/share/man/man1/xstdcmap.1.gz
/usr/share/man/man1/xtrap.1.gz
/usr/share/man/man1/xtrapin.1.gz
/usr/share/man/man1/xtrapinfo.1.gz
/usr/share/man/man1/xtrapout.1.gz
/usr/share/man/man1/xtrapproto.1.gz
/usr/share/man/man1/xtrapreset.1.gz
/usr/share/man/man1/xtrapstats.1.gz
/usr/share/man/man1/iceauth.1.gz
/usr/share/man/man1/xgamma.1.gz
/usr/share/man/man1/xrefresh.1.gz
/usr/share/man/man1/xtrapchar.1.gz
/usr/share/man/man1/xvidtune.1.gz
/usr/share/menu/x11-xserver-utils
/usr/bin/iceauth
/usr/bin/sessreg
/usr/bin/showrgb
/usr/bin/xcmsdb
/usr/bin/xgamma
/usr/bin/xhost
/usr/bin/xmodmap
/usr/bin/xrandr
/usr/bin/xrdb
/usr/bin/xrefresh
/usr/bin/xset
/usr/bin/xsetmode
/usr/bin/xsetpointer
/usr/bin/xsetroot
/usr/bin/xstdcmap
/usr/bin/xtrapchar
/usr/bin/xtrapin
/usr/bin/xtrapinfo
/usr/bin/xtrapout
/usr/bin/xtrapproto
/usr/bin/xtrapreset
/usr/bin/xtrapstats
/usr/bin/xvidtune
/etc/X11/app-defaults/Xvidtune
我们一个一个来介绍每个命令的用途。如果需要了解 X window 系统结构,可以参看这里
  • iceauth 和 xauth 类似,但是是作为 inter-client exchange 协议下的认证文件 .ICEauthority 的操纵程序。
  • sessreg 用于记录 X session 的会话记录到 utmp(记录登录登出)。
  • showrgb 显示系统已知颜色对应的 rgb。
  • xcmsdb(X color management system)用于加载、查询 X 的 device profile,如将 CIEXYZ 转换成为 RGB 的方法、gamma 信息。
  • xgamma 用于获得或者更改 X 显示的 gamma 值。
  • xhost 是一种 X server 的验证机制,是基于主机名/地址的,语法为 xhost + 开放给所有人,xhost - 仅仅允许 list 里面的主机,xhost +hostname 添加到 list 而 xhost -hostname 删去。
  • xmodmap 用于显示或者修改键盘或者鼠标映射,如 -pm 显示 modifier(如 Ctrl、Shift 等)、-pk 显示 keymap。可以通过 -e 执行一个命令或者使用一个文件作为命令序列输入。
  • xrandr 是 X 的一个 extention RandR 的命令行接口,用于设定一个 X 的大小、方向(旋转或者镜像)。ms 现在 NVIDIA 的驱动不大支持 xrandr,不爽... 一般用法为 xrandr -q 获得已有的输出设备支持的分辨率和刷新率,然后可以选择设定这些值,并且可以设定屏幕的朝向,如用 --output 屏幕 --reflect x 产生镜像翻转。
  • xrdb 是用于读入 X resource 的工具,X resource 一般存放在 .Xdefaults 里面,放有某些应用程序需要的一些配置,如 Emacs 的字体等等。这个我们会在后面对 X resource 的管理做出专门的讨论。
  • xrefresh 可以用来刷新一个 X screen,或者该 screen 的某一个部位。
  • xset 是一个强大的设置工具,如 b 设置 bell 的声音大小,bc 或者 -bc 设置或者关闭一个 bug compatability 模式,+/-dpms 是 enery star 的功能,fp 可以指定 X server 的 font path(避免修改系统文件 /etc/X11/xorg.conf),led 设定键盘上 LED 指示灯的状态,m 或者 mouse 设定鼠标灵敏程度(加速),r 控制按键自动重复输入(可以选择打开或者关闭对某些键的设置),s 设置 screen saver 的特性,q 显示已有配置。
  • xsetmode 设置输入装置的 mode 为绝对或者相对。
  • xsetpointer 设置 X 主要的 pointer 设备。
  • xsetroot 用于设定 X root window 的性质,如使用光标,使用 bitmap 作为背景,背景色等。
  • xstdcmap 用于设定 X standard color map,不知道有啥用...
  • xtrap* 命令是 X 的 XTrap extension 系列命令,似乎是为了方便 the capturing of server protocol and synthesizing core input events,这是啥 -,-bb
  • xvidtune 用于调整视频模式,如显示偏了,或者大了小了。

这里简单的叙述一下 xmodmap 的用法,keycode 就是按键的编号(数字),keysymname 是按键的符号名称。xmodmap 常用的命令有 keycode NUMBER = KEYSYMNAME 将某个 keycode 映射成为某 keysym。注意 KEYSYMNAME 可以有 8 项表示在有没有 modifier 情况下的结果,如 -pk 的输出
     10     0x0031 (1) 0x0021 (exclam)
11 0x0032 (2) 0x0040 (at)
12 0x0033 (3) 0x0023 (numbersign)
可见按键 1、2、3 是如何被映射的。keycode any = KEYSYMNAME 将未进行映射的 keycode 映射。keysym KEYSYMNAME = KEYSYMNAME 将 keysym 映射成为 keysym,比如要按下 A 出来 B,可以写 keysym a = b,注意中间的空格是不能省略的。clear MODIFIERNAME 清除掉某个 modifier,add MODIFIERNAME = KEYSYMNAME 添加一个 modifier,remove MODIFIERNAME = KEYSYMNAME 去掉一个 modifier,pointer = NUMBER 可以设置三个按键的作用,使用 pointer = default 恢复默认值。


注:
  • 为了不影响现有 X 的正常配置,进行某些实验时,建议另外打开一个 X,如 startx -- :1。

util-linux

该包中含有大量最常用的命令,集中在 /sbin、/usr/bin 和 /usr/sbin 中:
  • mkswap,用于在一个设备或者文件中创建 swap 分区。创建后需要通过 swapon 打开。分区类型为 0x82,不要和 Solaris 使用的分区类型混淆(也是 0x82)。
  • isosize 用于输出一个 iso9660 设备或者镜像文件的文件系统长度。
  • hwclock 用于访问硬件时钟,即 bios 内置时钟,可以同步该时钟和系统时钟(内核维护的时钟)。
  • mkfs.bfs 创建 SCO 的 BFS 文件系统。
  • fsck.cramfs 对 cramfs 文件系统进行检查。
  • mkfs.minix 创建 minix 文件系统。
  • blockdev 设置或显示 block device 的 ioctls,如读写属性,扇区大小,重新读入分区表或者 flush buffer。
  • cfdisk 分区程序,和 fdisk 不一样之处是用 curse/slang 库写的, TUI 要更好用一些。
  • fdisk 分区程序,没啥好说的,-l 会显示所有设备。
  • getty,作为守候某个线路如终端、串口的程序,将会为用户打开 login 提供登录。后面详细介绍。
  • mkfs.cramfs 创建 cramfs 文件系统,由于 cramfs 是压缩 ROM(Read-Only Memory)文件系统,只读,常用作 initrd 镜像文件,使用 zlib 压缩,最大文件不能超过 16Mb,文件系统最大只能稍微超过 256Mb(最后一个文件在 256Mb 块前开始,并可以扩展到 256Mb 以外)。因此该命令基本格式是 mkfs.cramfs dir img。
  • pivot_root 和 chroot 类似,但是目的不同,pivot_root 不同实现也不一样,pivot_root 把老的 / 挂在新 / 的子目录下,但是可能当前 / 没有更新(和实现相关),因此后面需要再次 chroot 进入新的 root。
  • sfdisk 也是一个维护分区的工具,比较不同的是可以调整分区大小,但是不能处理较大的分区(可用 GNU parted)。
  • ctrlaltdelete,设置按下 Ctrl-Alt-Del 的行为,分 hard 和 soft,前者不进行 sync 等前期操作,比较危险。
  • raw 将一个 character 设备绑定到一个 block 设备,这样可以用访问前者的方式访问后者,现在已经不多用了,推荐直接用 O_DIRECT 方式打开 block 设备。
  • fsck.minix 是 minix 文件系统查错程序。
  • mkfs 是创建文件系统的统一接口。通过 -t 指定类型,其余的和 mkfs.* 类型一致即可。
  • dmesg 可以显示内核在 boot 时候的信息,还可以清除(-c)kernel ring buffer,设置大小(-s)和级别(-n)。
  • more 标准分页阅读程序,建议用 less。
  • tailf 和 tail -f 类似,可以跟着文件的增长显示最后的几行,但是不像后者会在不增长时访问文件,因此不会更新该文件的 access timestamp。
  • fdformat,软盘低级格式化,ms 谬几个人用软盘了吧...
  • rtcwake 进入系统休眠状态,并设定重新醒来时间,这个将在后面休眠的专题里面讨论一下。
  • cytune 用于调整 Cyclades-Z 多端口串口卡的驱动参数。
  • tunelp 设定打印机(lp 设备)的参数,不过现在似乎直接用 cups 的人更多了吧 :-p
  • readprofile 读取 kernel profile,但是 kernel 必须打开 profile(boot 时加 profile=? 的参数)。
  • rdev 也是一个不被鼓励使用的命令,因为多数功能在非 i386 的系统上已经不能使用,取而代之的是直接用 boot loader 设定类似的参数,该命令和 rootflags、ramsize、vidmode 用于显示或者设定根分区、RAM disk 和视频模式的信息。
  • ldattach 将一个 line discipline 关联到串口设备,这样通过访问串口输入输出和在对应设备上是一个效果,如 TTY、SLIP、MOUSE、PPP 等。
  • chkdupexe 搜索 PATH 发现重名命令或者断掉的符号连接。
  • line 读入一行,与 read(bash 内部命令)类似。
  • rev 将输入每行翻转。
  • setterm 设定 term 性质,如 setterm -reset 和 reset 类似,光标显示与否(-cursor)等等。
  • partx 为给定的 block 设备指定分区表类型方便 kernel 分析该设备上的分区。和 fdisk 不同的是,可以使用该程序“告诉”内核添加分区或者删除,但是不写入到改设备上。
  • chrt 设定某进程 real-time 属性,好像 GNU libc 的文档有相关的论述。
  • taskset 可以将某个进程绑定到指定的 CPU 上。
  • ipcrm 是 IPC 管理,移除 message queue、semaphore 或者 shared memory。
  • ionice 设置一个程序的 IO 优先级别。
  • addpart/delpart 添加删除分区。
  • setsid 设置某程序在新的 session 中执行。
  • pg,感觉和 more 一样 @@
  • ipcs,显示 IPC 信息。
  • getopt,和 C 里面 getopt 函数类似,用于 parse 程序输入的参数。这里有例子。
  • flock,处理文件锁,如 -s 共享锁,-e 排除锁,-n 非阻塞式(fail 即返回),-u 开锁等。
  • whereis 显示程序位置。
  • mcookie 产生 magic cookie 的小程序。
  • namei,显示一个 path 上每个点的类型,如目录、设备还是别的。
  • ddate 将 Gregorian date 转换称为 Discordian date。
  • linux32/linux64/i386 设定对应结构下的环境变量。

这里我们看看一些重要的应用。比如一般在 /etc/inittab 里面有打开终端的命令,这也是一般在文本模式下看到的东西,
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100

# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3


相关文件:
ncurses-bin: reset
parted: parted