今天郑州又下雨了,我和王辉被困在大学路口的蛋糕店里。
终于见识到了什么叫瓢泼大雨,也看到了中原路上的奇观,你见过往上喷水的下水道么?
中原路上的两个我可以看到的下水道井,像喷泉一样,喷出一米来高水柱,水压使得井盖咣咣作响……可惜没有相机,不然可以拍下来,到大河报发表。
七月, 2005
29
七 05
今天郑州又下雨了
29
七 05
使用myisamchk进行崩溃恢复
13.4 使用myisamchk进行崩溃恢复
2004-02-12 MySQL 译者:晏子 http://www.mysql.com/doc.html
由MySQL用来存储数据的文件格式以已经被广泛地测试过,但是总是有外部情况可以导致数据库表被破坏:
mysqld进程在一个写入当中被杀死。
计算机的意外关闭(例如,如果计算机掉电)。
一个硬件错误
这章描述如何检查和处理在MySQL数据库中的数据损坏。如果你的表损坏很多,你应该尝试找出其原因!见G.1 调试一个MySQL服务器。
在执行崩溃恢复时,理解在一个数据库中的每一个表tbl_name对应的在数据库目录中的3个文件是很重要的:
文件 用途
“tbl_name.frm” 表定义(表格)文件
“tbl_name.MYD” 数据文件
“tbl_name.MYI” 索引文件
这3个文件的每一个文件类型可能遭受不同形式的损坏,但是问题最常发生在数据文件和索引文件。
myisamchk通过一行一行地创建一个“.MYD”(数据 )文件的副本来工作,它通过由删除老的“.MYD 文件并且重命名新文件到原来的文件名结束修复阶段。如果你使用–quick,myisamchk不创建一个临时“.MYD”文件,只是假定“.MYD”文件是正确的并且仅创建一个新的索引文件,不接触“.MYD”文件,这是安全的,因为myisamchk自动检测“.MYD”文件是否损坏并且在这种情况下,放弃修复。你也可以给myisamchk两个–quick选项。在这种情况下,myisamchk不会在一些错误上(象重复键)放弃,相反试图通过修改“.MYD”文件解决它们。通常,只有在你在太少的空闲磁盘空间上实施一个正常修复,使用两个–quick选项才有用。在这种情况下,你应该至少在运行myisamchk前做一个备份。
13.4.1 怎样检查表的错误
为了检查一张表,使用下列命令:
myisamchk tbl_name
这能找出所有错误的99.99%。它不能找出的是仅仅涉及数据文件的损坏(这很不常见)。如果你想要检查一张表,你通常应该没有选项地运行myisamchk或用-s或–silent选项的任何一个。
myisamchk -e tbl_name
它做一个完全彻底的数据检查(-e意思是“扩展检查”)。它对每一行做每个键的读检查以证实他们确实指向正确的行。这在一个有很多键的大表上可能花很长时间。myisamchk通常将在它发现第一个错误以后停止。如果你想要获得更多的信息,你能增加–verbose(-v)选项。这使得myisamchk继续一直到最多20个错误。在一般使用中,一个简单的myisamchk(没有除表名以外的参数)就足够了。
myisamchk -e -i tbl_name
象前面的命令一样,但是-i选项告诉myisamchk还打印出一些统计信息。
13.4.2 怎样修复表
一张损坏的表的症状通常是查询意外中断并且你能看到例如这些错误:
“tbl_name.frm”被锁定不能改变。
不能找到文件“tbl_name.MYI”(Errcode :### )。
从表处理器的得到错误###(此时,错误135是一个例外)。
意外的文件结束。
记录文件被毁坏。
在这些情况下,你必须修复表。myisamchk通常能检测并且修复出错的大部分东西。
修复过程包含最多4个阶段,在下面描述。在你开始前,你应该cd到数据库目录和检查表文件的权限,确保他们可被运行mysqld的Unix用户读取(和你,因为你需要存取你正在检查的文件)。如果它拒绝你修改文件,他们也必须是可被你写入的。
阶段1:检查你的表
运行myisamchk *.MYI或(myisamchk -e *.MYI,如果你有更多的时间)。使用-s(沉默)选项禁止不必要的信息。
你必须只修复那些myisamchk报告有一个错误的表。对这样的表,继续到阶段2。
如果在检查时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
阶段 2 :简单安全的修复
首先,试试myisamchk -r -q tbl_name(-r -q意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切和在数据文件指向正确地点的删除连接,这应该管用并且表可被修复。开始修理下一张表。否则,使用下列过程:
在继续前做数据文件的一个备份。
使用myisamchk -r tbl_name(-r意味着“恢复模式”)。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。
如果前面的步骤失败,使用myisamchk –safe-recover tbl_name。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况(但是更慢)。
如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
阶段 3 :困难的修理
如果在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你只应该到这个阶段 。在这种情况下,创建一个新的索引文件是必要的。按如下这样做:
把数据文件移更安全的地方。
使用表描述文件创建新的(空)数据和索引文件:
shell> mysql db_name
mysql> DELETE FROM tbl_name;
mysql> quit
将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)
回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。
阶段4:非常困难的修复
只有描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。
从一个备份恢复描述文件并且回到阶段3。你也可以恢复索引文件并且回到阶段2。对后者,你应该用myisamchk -r启动。
如果你没有一个备份但是确切地知道表是怎样被创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述和索引文件移到破坏的数据库中。这给了你新的描述和索引文件,但是让数据文件独自留下来了。回到阶段2并且尝试重建索引文件。
13.4.3 表优化
为了组合成碎片的记录并且消除由于删除或更新记录而浪费的空间, 以恢复模式运行myisamchk:
shell> myisamchk -r tbl_name
你可以用SQL的OPTIMIZE TABLE语句使用的相同方式来优化一张表,OPTIMIZE TABLE比较容易,但是myisamchk更快。也没有在一个实用程序和服务器之间不必要的交互可能性,因为当你使用OPTIMIZE TABLE时,服务器做所有的工作。
myisamchk也有你可用来改进一个表的性能的很多其他选项:
-S, –sort-index
-R index_num, –sort-records=index_num
-a, –analyze
对于选项完整的描述见13.1.1 myisamchk调用语法。
28
七 05
使用logrotate来轮转linux上的日志
对于Linux 的系统安全来说,日志文件是极其重要的工具。系统管理员可以使用logrotate 程序用来管理系统中的最新的事件。
对于Linux 的系统安全来说,日志文件是极其重要的工具。
系统管理员可以使用logrotate 程序用来管理系统中的最新的事件。logrotate 还可以用来备份日志文件,本篇将通过以下几部分来介绍日志文件的管理:
1、logrotate 配置
2、缺省配置 logrotate
3、使用include 选项读取其他配置文件
4、使用include 选项覆盖缺省配置
5、为指定的文件配置转储参数
一、logrotate 配置
logrotate 程序是一个日志文件管理工具。用来把旧的日志文件删除,并创建新的日志文件,我们把它叫做“转储”。我们可以根据日志文件的大小,也可以根据其天数来转储,这个过程一般通过 cron 程序来执行。
logrotate 程序还可以用于压缩日志文件,以及发送日志到指定的E-mail 。
logrotate 的配置文件是 /etc/logrotate.conf。主要参数如下表:
参数 功能
compress 通过gzip 压缩转储以后的日志
nocompress 不需要压缩时,用这个参数
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
create mode owner group 转储文件,使用指定的文件模式创建新的日志文件
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。
errors address 专储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。
notifempty 如果是空文件的话,不转储
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
tabootext [+] list 让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~
size size 当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem).
二、缺省配置 logrotate
logrotate 缺省的配置募 ?/etc/logrotate.conf。
Red Hat Linux 缺省安装的文件内容是:
# see “man logrotate” for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# send errors to root
errors root
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
#compress
1
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own lastlog or wtmp –we&aposll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
rotate 1
}
/var/log/lastlog {
monthly
rotate 1
}
# system-specific logs may be configured here
缺省的配置一般放在logrotate.conf 文件的最开始处,影响整个系统。在本例中就是前面12行。
第三行weekly 指定所有的日志文件每周转储一次。
第五行 rotate 4 指定转储文件的保留 4份。
第七行 errors root 指定错误信息发送给root。
第九行create 指定 logrotate 自动建立新的日志文件,新的日志文件具有和
原来的文件一样的权限。
第11行 #compress 指定不压缩转储文件,如果需要压缩,去掉注释就可以了。
三、使用include 选项读取其他配置文件
include 选项允许系统管理员把分散到几个文件的转储信息,集中到一个
主要的配置文件。当 logrotate 从logrotate.conf 读到include 选项时,会从指定文件读入配置信息,就好像他们已经在/etc/logrotate.conf 中一样。
第13行 include /etc/logrotate.d 告诉 logrotate 读入存放在/etc/logrotate.d 目录中的日志转储参数,当系统中安装了RPM 软件包时,使用include 选项十分有用。RPM 软件包的日志转储参数一般存放在/etc/logrotate.d 目录。
include 选项十分重要,一些应用把日志转储参数存放在 /etc/logrotate.d 。
典型的应用有:apache, linuxconf, samba, cron 以及syslog。
这样,系统管理员只要管理一个 /etc/logrotate.conf 文件就可以了。
四、使用include 选项覆盖缺省配置
当 /etc/logrotate.conf 读入文件时,include 指定的文件中的转储参数将覆盖缺省的参数,如下例:
# linuxconf 的参数
/var/log/htmlaccess.log
{ errors jim
notifempty
nocompress
weekly
prerotate
/usr/bin/chattr -a /var/log/htmlaccess.log
endscript
postrotate
/usr/bin/chattr +a /var/log/htmlaccess.log
endscript
}
/var/log/netconf.log
{ nocompress
monthly
}
在这个例子中,当 /etc/logrotate.d/linuxconf 文件被读入时,下面的参数将覆盖/etc/logrotate.conf中缺省的参数。
Notifempty
errors jim
五、为指定的文件配置转储参数
经常需要为指定文件配置参数,一个常见的例子就是每月转储/var/log/wtmp。为特定文件而使用的参数格式是:
# 注释
/full/path/to/file
{
option(s)
}
下面的例子就是每月转储 /var/log/wtmp 一次:
#Use logrotate to rotate wtmp
/var/log/wtmp
{
monthly
rotate 1
}
六、其他需要注意的问题
1、尽管花括号的开头可以和其他文本放在同一行上,但是结尾的花括号必须单独成行。
2、使用 prerotate 和 postrotate 选项
下面的例子是典型的脚本 /etc/logrotate.d/syslog,这个脚本只是对
/var/log/messages 有效。
/var/log/messages
{
prerotate
/usr/bin/chattr -a /var/log/messages
endscript
postrotate
/usr/bin/kill -HUP syslogd
/usr/bin/chattr +a /var/log/messages
endscript
}
第一行指定脚本对 /var/log messages 有效
花ê哦阅诓康慕疟驹诵杏? /var/log/messages
prerotate 命令指定转储以前的动作/usr/bin/chattr -a 去掉/var/log/messages文件的“只追加”属性 endscript 结束 prerotate 部分的脚本postrotate 指定转储后的动作
/usr/bin/killall -HUP syslogd
用来重新初始化系统日志守护程序 syslogd
/usr/bin/chattr +a /var/log/messages
重新为 /var/log/messages 文件指定“只追加”属性,这样防治程序员或用户覆盖此文件。
最后的 endscript 用于结束 postrotate 部分的脚本
3、logrotate 的运行分为三步:
判断系统的日志文件,建立转储计划以及参数,通过cron daemon 运行下面的代码是 Red Hat Linux 缺省的crontab 来每天运行logrotate。
#/etc/cron.daily/logrotate
#! /bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
4、/var/log/messages 不能产生的原因:
这种情况很少见,但是如果你把/etc/services 中的 514/UDP 端口关掉的话,这个文件就不能产生了。
小结:本文通过对Red Hat 系统上典型的logrotate 配置例子的介绍,详细说明了logrotate 程序的应用方法。希望对所有Linux 系统管理员有所帮助。管理好,分析好日志文件是系统安全的第一步,在以后的文章里还会介绍另外一个检查日志的好东东 logcheck。
23
七 05
UNIX/Linux常用的命令
名 称:cat
使用权限:所有使用者
使用方式:cat [-AbeEnstTuv] [--help] [--version] fileName
说 明:把档案串连接后传到基本输出(屏幕或加 > fileName 到另一个档案)
参 数:
-n 或 –number 由 1 开始对所有输出的行数编号
-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 –show-nonprinting
范 例:
cat -n textfile1 > textfile2 把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
cat -b textfile1 textfile2 >> textfile3 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3
名 称 : cd
使用权限 : 所有使用者
使用方式 : cd [dirName]
说 明 : 变换工作目录至 dirName。 其中 dirName 表示法可为绝对路径或相对路径。若目录名称省略,则变换至使用者的 home directory (也就是刚 login 时所在的目录)。另外,”~” 也表示为 home directory 的意思,”.” 则是表示目前所在的目录,”..” 则表示目前目录位置的上一层目录。
范 例 :
跳到 /usr/bin/ :
cd /usr/bin
跳到自己的 home directory :
cd ~
跳到目前目录的上上两层 :
cd ../..
指令名称 : chmod
使用权限 : 所有使用者
使用方式 : chmod [-cfvR] [--help] [--version] mode file…
说 明 : Linux/Unix 的档案存取权限分为三级 : 档案拥有者、群组、其他。利用 chmod 可以藉以控制档案如何被他人所存取。
参 数 :
mode : 权限设定字串,格式如下 : [ugoa...][[+-=][rwxX]…][,...],其中u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
+ 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
-c : 若该档案权限确实已经更改,才显示其更改动作
-f : 若该档案权限无法被更改也不要显示错误讯息
-v : 显示权限变更的详细资料
-R : 对目前目录下的所有档案与子目录进行相同的权限变更(即以递回的方式逐个变更)
–help : 显示辅助说明
–version : 显示版本
范 例 :
将档案 file1.txt 设为所有人皆可读取 :
chmod ugo+r file1.txt
将档案 file1.txt 设为所有人皆可读取 :
chmod a+r file1.txt
将档案 file1.txt 与 file2.txt 设为该档案拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入 :
chmod ug+w,o-w file1.txt file2.txt
将 ex1.py 设定为只有该档案拥有者可以执行 :
chmod u+x ex1.py
将目前目录下的所有档案与子目录皆设为任何人可读取 :
chmod -R a+r *
此外chmod也可以用数字来表示权限如 chmod 777 file
语法为:chmod abc file
其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
r=4,w=2,x=1
若要rwx属性则4+2+1=7;
若要rw-属性则4+2=6;
若要r-x属性则4+1=7。
范例:
chmod a=rwx file
和
chmod 777 file
效果相同
chmod ug=rwx,o=x file
和
chmod 771 file
效果相同
若用chmod 4755 filename可使此程式具有root的权限
指令名称 : chown
使用权限 : root
使用方式 : chmod [-cfhvR] [--help] [--version] user[:group] file…
说 明 : Linux/Unix 是多人多工作业系统,所有的档案皆有拥有者。利用chown 可以将档案的拥有者加以改变。一般来说,这个指令只有是由系统管理者(root)所使用,一般使用者没有权限可以改变别人的档案拥有者,也没有权限可以自己的档案拥有者改设为别人。只有系统管理者(root)才有这样的权限。
参 数 :
user : 新的档案拥有者的使用者
IDgroup : 新的档案拥有者的使用者群体(group)
-c : 若该档案拥有者确实已经更改,才显示其更改动作
-f : 若该档案拥有者无法被更改也不要显示错误讯息
-h : 只对于连结(link)进行变更,而非该 link 真正指向的档案
-v : 显示拥有者变更的详细资料
-R : 对目前目录下的所有档案与子目录进行相同的拥有者变更(即以递回的方式逐个变更)
–help : 显示辅助说明
–version : 显示版本
范 例 :
将档案 file1.txt 的拥有者设为 users 群体的使用者 jessie :
chown jessie:users file1.txt
将目前目录下的所有档案与子目录的拥有者皆设为 users 群体的使用者 lamport :
chmod -R lamport:users *
名 称:cp
使用权限:所有使用者
使用方式:
cp [options] source dest
cp [options] source… directory
说 明:将一个档案拷贝至另一档案,或将数个档案拷贝至另一目录。
参 数:
-a 尽可能将档案状态、权限等资料都照原状予以复制。
-r 若 source 中含有目录名,则将目录下之档案亦皆依序拷贝至目的地。
-f 若目的地已经有相同档名的档案存在,则在复制前先予以删除再行复制。
范 例:
将档案 aaa 复制(已存在),并命名为 bbb :
cp aaa bbb
将所有的C语言程式拷贝至 Finished 子目录中 :
cp *.c Finished
名 称:cut
使用权限:所有使用者
用 法:cut -cnum1-num2 filename
说 明:显示每行从开头算起 num1 到 num2 的文字。
范 例:
shell>> cat example
test2
this is test1
shell>> cut -c0-6 example ## print 开头算起前 6 个字元
test2
this i
名 称 : find
用 法 : find
使用说明 :
将档案系统内符合 expression 的档案列出来。你可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。
find 根据下列规则判断 path 和 expression,在命令列上第一个 – ( ) , ! 之前的部份为 path,之后的是 expression。如果 path 是空字串则使用目前路径,如果 expression 是空字串则使用 -print 为预设 expression
expression 中可使用的选项有二三十个之多,在此只介绍最常用的部份。
-mount, -xdev : 只检查和指定目录在同一个档案系统下的档案,避免列出其它档案系统中的档案
-amin n : 在过去 n 分钟内被读取过
-anewer file : 比档案 file 更晚被读取过的档案
-atime n : 在过去 n 天过读取过的档案
-cmin n : 在过去 n 分钟内被修改过
-cnewer file :比档案 file 更新的档案
-ctime n : 在过去 n 天过修改过的档案
-empty : 空的档案-gid n or -group name : gid 是 n 或是 group 名称是 name
-ipath p, -path p : 路径名称符合 p 的档案,ipath 会忽略大小写
-name name, -iname name : 档案名称符合 name 的档案。iname 会忽略大小写
-size n : 档案大小 是 n 单位,b 代表 512 位元组的区块,c 表示字元数,k 表示 kilo bytes,w 是二个位元组。
-type c : 档案类型是 c 的档案。
d: 目录
c: 字型装置档案
b: 区块装置档案
p: 具名贮列
f: 一般档案
l: 符号连结
s: socket
-pid n : process id 是 n 的档案
你可以使用 ( ) 将运算式分隔,并使用下列运算。
exp1 -and exp2
! expr
-not expr
exp1 -or exp2
exp1, exp2
范例:
将目前目录及其子目录下所有延伸档名是 c 的档案列出来。
# find . -name “*.c”
将目前目录其其下子目录中所有一般档案列出
# find . -ftype f
将目前目录及其子目录下所有最近 20 分钟内更新过的档案列出
# find . -ctime -20
名 称:less
使用权限:所有使用者
使用方式:
less [Option] filename
说 明:
less 的作用与 more 十分相似,都可以用来浏览文字档案的内容,不同的是 less 允许使用者往回卷动
以浏览已经看过的部份,同时因为 less 并未在一开始就读入整个档案,因此在遇上大型档案的开启时,会比一般的文书编辑器(如 vi)来的快速。
指令名称 : ln
使用权限 : 所有使用者
使用方式 : ln [options] source dist,其中 option 的格式为 :
[-bdfinsvF] [-S backup-suffix] [-V {numbered,existing,simple}]
[--help] [--version] [--]
说 明 : Linux/Unix 档案系统中,有所谓的连结(link),我们可以将其视为档案的别名,而连结又可分为两种 : 硬连结(hard link)与软连结(symbolic link),硬连结的意思是一个档案可以有多个名称,而软连结的方式则是产生一个特殊的档案,该档案的内容是指向另一个档案的位置。
硬连结是存在同一个档案系统中,而软连结却可以跨越不同的档案系统。
ln source dist 是产生一个连结(dist)到 source,至于使用硬连结或软链结则由参数决定。
不论是硬连结或软链结都不会将原本的档案复制一份,只会占用非常少量的磁碟空间。
-f : 链结时先将与 dist 同档名的档案删除
-d : 允许系统管理者硬链结自己的目录
-i : 在删除与 dist 同档名的档案时先进行询问
-n : 在进行软连结时,将 dist 视为一般的档案
-s : 进行软链结(symbolic link)
-v : 在连结之前显示其档名
-b : 将在链结时会被覆写或删除的档案进行备份
-S SUFFIX : 将备份的档案都加上 SUFFIX 的字尾
-V METHOD : 指定备份的方式
–help : 显示辅助说明
–version : 显示版本
范例 :
将档案 yy 产生一个 symbolic link : zz
ln -s yy zz
将档案 yy 产生一个 hard link : zz
ln yy xx
名 称:locate
使用权限:所有使用者
使用方式: locate [-q] [-d ] [--database=]
locate [-r ] [--regexp=]
locate [-qv] [-o ] [--output=]
locate [-e ] [-f ] <[-l ] [-c]
<[-U ] [-u]>
locate [-Vh] [--version] [--help]
说 明:
locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案。其方法是先建立一个包括系统内所有档案名称及路径的资料库,之后当寻找时就只需查询这个资料库,而不必实际深入档案系统之中了。
在一般的 distribution 之中,资料库的建立都被放在 contab 中自动执行。一般使用者在使用时只要用
# locate your_file_name
的型式就可以了。
参 数:
-u
-U
建立资料库,-u 会由根目录开始,-U 则可以指定开始的位置。
-e
将排除在寻找的范围之外。
-l
如果 是 1.则启动安全模式。在安全模式下,使用者不会看到权限无法看
到的档案。这会始速度减慢,因为 locate 必须至实际的档案系统中取得
档案的权限资料。
-f
将特定的档案系统排除在外,例如我们没有到理要把 proc 档案系统中的
档案放在资料库中。
-q
安静模式,不会显示任何错误讯息。
-n
至多显示 个输出。
-r
使用正规运算式 做寻找的条件。
-o
指定资料库存的名称。
-d
指定资料库的路径
-h
显示辅助讯息
-v
显示更多的讯息
-V
显示程式的版本讯息 范例:
locate chdrv : 寻找所有叫 chdrv 的档案
locate -n 100 a.out : 寻找所有叫 a.out 的档案,但最多只显示 100
个
locate -u : 建立资料库
名 称 : ls
使用权限 : 所有使用者
使用方式 : ls [-alrtAFR] [name...]
说 明 : 显示指定工作目录下之内容(列出目前工作目录所含之档案及子目录)。
-a 显示所有档案及目录 (ls内定将档案名或目录名称开头为”.”的视为隐藏档,不会列出)
-l 除档案名称外,亦将档案型态、权限、拥有者、档案大小等资讯详细列出
-r 将档案以相反次序显示(原定依英文字母次序)
-t 将档案依建立时间之先后次序列出
-A 同 -a ,但不列出 “.” (目前目录) 及 “..” (父目录)
-F 在列出的档案名称后加一符号;例如可执行档则加 “*”, 目录则加 “/”
-R 若目录下有档案,则以下之档案亦皆依序列出
范 例:
列出目前工作目录下所有名称是 s 开头的档案,愈新的排愈后面 :
ls -ltr s*
将 /bin 目录以下所有目录及档案详细资料列出 :
ls -lR /bin
列出目前工作目录下所有档案及目录;目录于名称后加 “/”, 可执行档于名称后加 “*” :
ls -AF
名 称:more
使用权限:所有使用者
使用方式:more [-dlfpcsu] [-num] [+/pattern] [+linenum] [fileNames..]
说 明:类似 cat ,不过会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h 。
参 数:-num 一次显示的行数
-d 提示使用者,在画面下方显示 [Press space to continue, q to quit.] ,如果使用者按错键,则会显示 [Press h for instructions.] 而不是哔声
-l 取消遇见特殊字元 ^L(送纸字元)时会暂停的功能
-f 计算行数时,以实际上的行数,而非自动换行过后的行数(有些单行字数太长的会被扩展为两行或两行以上)
-p 不以卷动的方式显示每一页,而是先清除萤幕后再显示内容
-c 跟 -p 相似,不同的是先显示内容再清除其他旧资料
-s 当遇到有连续两行以上的空白行,就代换为一行的空白行
-u 不显示下引号 (根据环境变数 TERM 指定的 terminal 而有所不同)
+/ 在每个档案显示前搜寻该字串(pattern),然后从该字串之后开始显示
+num 从第 num 行开始显示
fileNames 欲显示内容的档案,可为复数个数
范 例:
more -s testfile 逐页显示 testfile 之档案内容,如有连续两行以上空白行则以一行空白行显示。
more +20 testfile 从第 20 行开始显示 testfile 之档案内容。
名 称:mv
使用权限:所有使用者
使用方式:
mv [options] source dest
mv [options] source… directory
说 明:将一个档案移至另一档案,或将数个档案移至另一目录。
参 数:-i 若目的地已有同名档案,则先询问是否覆盖旧档。
范 例:
将档案 aaa 更名为 bbb :
mv aaa bbb
将所有的C语言程式移至 Finished 子目录中 :
mv -i *.c
名 称:rm
使用权限:所有使用者
使用方式:rm [options] name…
说 明:删除档案及目录。
选 项:
-i 删除前逐一询问确认。
-f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。
-r 将目录及以下之档案亦逐一删除。
范 例:删除所有C语言程式档;删除前逐一询问确认 。
rm -i *.c
将 Finished 子目录及子目录中所有档案删除 :
rm -r Finished
名 称:rmdir
使用权限:于目前目录有适当权限的所有使用者
使用方式:rmdir [-p] dirName
说 明:删除空的目录。
参 数:
-p 是当子目录被删除后使它也成为空目录的话,则顺便一并删除。
范 例:
将工作目录下,名为 AAA 的子目录删除 :
rmdir AAA
在工作目录下的 BBB 目录中,删除名为 Test 的子目录。若 Test 删除后
,BBB 目录成为空目录,则 BBB 亦予删除。
rmdir -p BBB/Test
名 称:split
使用权限:所有使用者
使用方式:split [OPTION] [INPUT [PREFIX]]
说 明:将一个档案分割成数个。而从 INPUT 分割输出成固定大小的档
案,其档名依序为 PREFIXaa, PREFIXab…;PREFIX 预设值为 `x。若没
有 INPUT 档或为 `-,则从标准输入读进资料。
选 项:
-b, –bytes=SIZE
SIZE 值为每一输出档案的大小,单位为 byte。
-C, –line-bytes=SIZE
每一输出档中,单行的最大 byte 数。
-l, –lines=NUMBER
NUMBER 值为每一输出档的列数大小。
-NUMBER
与 -l NUMBER 相同。
–verbose
于每个输出档被开启前,列印出侦错资讯到标准错误输出。
–help
显示辅助资讯然后离开。
–version
列出版本资讯然后离开。
SIZE 可加入单位: b 代表 512, k 代表 1K, m 代表 1 Meg。
范 例:
PostgresSQL 大型资料库备份与回存:
因 Postgres 允许表格大过你系统档案的最大容量,所以要将表格 dump
到单一的档案可能会有问题,使用 split进行档案分割。
% pg_dump dbname | split -b 1m – filename.dump.
重新载入
% createdb dbname
% cat filename.dump.* | pgsql dbname
名 称:touch
使用权限:所有使用者
使用方式:
touch [-acfm]
[-r reference-file] [--file=reference-file]
[-t MMDDhhmm[[CC]YY][.ss]]
[-d time] [--date=time] [--time={atime,access,use,mtime,modify}]
[--no-create] [--help] [--version]
file1 [file2 ...]
说明:
touch 指令改变档案的时间记录。 ls -l 可以显示档案的时间记录。
参数:
a 改变档案的读取时间记录。
m 改变档案的修改时间记录。
c 假如目的档案不存在,不会建立新的档案。与 –no-create 的效果一样
。
f 不使用,是为了与其他 unix 系统的相容性而保留。
r 使用参考档的时间记录,与 –file 的效果一样。
d 设定时间与日期,可以使用各种不同的格式。
t 设定档案的时间记录,格式与 date 指令相同。
–no-create 不会建立新档案。
–help 列出指令格式。
–version 列出版本讯息。
范例:
最简单的使用方式,将档案的时候记录改为现在的时间。若档案不存在,
系统会建立一个新的档案。
touch file
touch file1 file2
将 file 的时间记录改为 5 月 6 日 18 点 3 分,公元两千年。时间的格
式可以参考 date 指令,至少需输入 MMDDHHmm ,就是月日时与分。
touch -c -t 05061803 file
touch -c -t 050618032000 file
将 file 的时间记录改变成与 referencefile 一样。
touch -r referencefile file
将 file 的时间记录改成 5 月 6 日 18 点 3 分,公元两千年。时间可以
使用 am, pm 或是 24 小时的格式,日期可以使用其他格式如 6 May 2000
。
touch -d “6:03pm” file
touch -d “05/06/2000″ file
touch -d “6:03pm 05/06/2000″ file
22
七 05
什么是GMT,什么是UTC
什么是GMT,什么是UTC
0.时标
时标意指一种将时间分配到事件的制度。现时有两类时间标准广泛被采用。一种是基于天文学,另一种则以原子振动的频率作为依据。
1.视太阳时
视太阳时是一种源于太阳所见位置的时间标准。日晷可直接显示视太阳时。
2.UT0
由于地球轨道并非圆形,其运行速度又随着地球与太阳的距离改变而出现变化,因此视太阳时欠缺均匀性。视太阳日的长度同时亦受到地球自转轴相对轨道面的倾斜度所影响。为着要纠正上述的不均匀性,天文学家计算地球非圆形轨迹与极轴倾斜对视太阳时的效应。平太阳时就是指经修订后的视太阳时。在格林尼治子午线上的平太阳时称为世界时(UT0),又叫格林尼治平时(GMT)。
3.UT1
UT1 与 UT2 是两种较 UT0 均匀的时标。随着较为精确的时钟面世,天文学家发现在不同地点量度的世界时出现差别。这种差别是由于地轴摆动而引起的。各地天文台详细测量了地轴摆动的影响后,制定了一种称为 UT1 的新时标将这种影响删除。
4.UT2
在时钟的精确度进一步改进后,又发现 UT1 具有周期性变化。这种变化是由地球自转率的季节性变动引起的。上述影响经修正后,得到一种更加均匀的时标称为 UT2。
5.国际原子时(TAI):
1967年的第13届国际度量衡会议上通过了一项决议,采纳以下定义代替秒的天文定义:一秒为铯-133原子基态两个超精细能级间跃迁辐射9,192,631,770周所持续的时间。国际原子时是根据以上秒的定义的一种国际参照时标,属国际单位制(SI)。
国际原子时标是一种连续性时标,由1958年1月1日0时0分0秒起,以日、时、分、秒计算。原子时标的准确度为每日数纳秒,而世界时的准确度则只为数毫秒。
6.协调世界时(UTC):
一种称为协调世界时的折衷时标于1972年面世。为了确保协调世界时与世界时(UT1)相差不会超过0.9秒,有需要时便会在协调世界时内加上正或负闰秒。因此协调世界时与国际原子时(TAI)之间会出现若干整数秒的差别。位于巴黎的国际地球自转事务中央局(IERS)负责决定何时加入闰秒。
22
七 05
用日志系统保护Linux安全
用日志系统保护Linux安全
Linux系统中的日志子系统对于系统安全来说非常重要,它记录了系统每天发生的各种各样的事情,包括那些用户曾经或者正在使用系统,可以通过日志来检查错误发生的原因,更重要的是在系统受到黑客攻击后,日志可
以记录下攻击者留下的痕迹,通过查看这些痕迹,系统管理员可以发现黑客攻击的某些手段以及特点,从而能够进行处理工作,为抵御下一次攻击做好准备。
在Linux系统中,有三类主要的日志子系统:
● 连接时间日志: 由多个程序执行,把记录写入到/var/log/wtmp和/var/run/utmp,login等程序会更新wtmp和utmp文件,使系统管理员能够跟踪谁在何时登录到系统。
● 进程统计: 由系统内核执行,当一个进程终止时,为每个进程往进程统计文件(pacct或acct)中写一个记录。进程统计的目的是为系统中的基本服务提供命令使用统计。
● 错误日志: 由syslogd(8)守护程序执行,各种系统守护进程、用户程序和内核通过syslogd(3)守护程序向文件/var/log/messages报告值得注意的事件。另外有许多Unix程序创建日志。像HTTP和FTP这样提供网络服务的服务器也保持详细的日志。
Linux下日志的使用
1.基本日志命令的使用
utmp、wtmp日志文件是多数Linux日志子系统的关键,它保存了用户登录进入和退出的记录。有关当前登录用户的信息记录在文件utmp中; 登录进入和退出记录在文件wtmp中; 数据交换、关机以及重启的机器信息也都记录在wtmp文件中。所有的记录都包含时间戳。时间戳对于日志来说非常重要,因为很多攻击行为分析都是与时间有极大关系的。这些文件在具有大量用户的系统中增长十分迅速。例如wtmp文件可以无限增长,除非定期截取。许多系统以一天或者一周为单位把wtmp配置成循环使用。它通常由cron运行的脚本来修改,这些脚本重新命名并循环使用wtmp文件。
utmp文件被各种命令文件使用,包括who、w、users和finger。而wtmp文件被程序last和ac使用。 但它们都是二进制文件,不能被诸如tail命令剪贴或合并(使用cat命令)。用户需要使用who、w、users、last和ac来使用这两个文件包含的信息。具体用法如下:
who命令: who命令查询utmp文件并报告当前登录的每个用户。Who的缺省输出包括用户名、终端类型、登录日期及远程主机。使用该命令,系统管理员可以查看当前系统存在哪些不法用户,从而对其进行审计和处理。例如: 运行who命令显示如下:
[root@working]# who
root pts/0 May 9 21:11 (10.0.2.128)
root pts/1 May 9 21:16 (10.0.2.129)
lhwen pts/7 May 9 22:03 (10.0.2.27)
如果指明了wtmp文件名,则who命令查询所有以前的记录。例如命令who /var/log/wtmp将报告自从wtmp文件创建或删改以来的每一次登录。
日志使用注意事项
系统管理人员应该提高警惕,随时注意各种可疑状况,并且按时和随机地检查各种系统日志文件,包括一般信息日志、网络连接日志、文件传输日志以及用户登录日志等。在检查这些日志时,要注意是否有不合常理的时间记载。例如:
■ 用户在非常规的时间登录;
■ 不正常的日志记录,比如日志的残缺不全或者是诸如wtmp这样的日志文件无故地缺少了中间的记录文件;
■ 用户登录系统的IP地址和以往的不一样;
■ 用户登录失败的日志记录,尤其是那些一再连续尝试进入失败的日志记录;
■ 非法使用或不正当使用超级用户权限su的指令;
■ 无故或者非法重新启动各项网络服务的记录。
另外, 尤其提醒管理人员注意的是: 日志并不是完全可靠的。高明的黑客在入侵系统后,经常会打扫现场。所以需要综合运用以上的系统命令,全面、综合地进行审查和检测,切忌断章取义,否则很难发现入侵或者做出错误的判断。
users命令: users用单独的一行打印出当前登录的用户,每个显示的用户名对应一个登录会话。如果一个用户有不止一个登录会话,那他的用户名将显示相同的次数。运行该命令将如下所示:
[root@working]# users
root root //只登录了一个Root权限的用户
last命令: last命令往回搜索wtmp来显示自从文件第一次创建以来登录过的用户。系统管理员可以周期性地对这些用户的登录情况进行审计和考核,从而发现其中存在的问题,确定不法用户,并进行处理。运行该命令,如下所示:
[root@working]# last
devin pts/1 10.0.2.221 Mon Jul 21 15:08-down (8+17:46)
devin pts/1 10.0.2.221 Mon Jul 21 14:42 – 14:53 (00:11)
changyi pts/2 10.0.2.141 Mon Jul 21 14:12 – 14:12 (00:00)
devin pts/1 10.0.2.221 Mon Jul 21 12:51 – 14:40 (01:49)
reboot system boot 2.4.18 Fri Jul 18 15:42 (11+17:13)
reboot system boot 2.4.18 Fri Jul 18 15:34 (00:04)
reboot system boot 2.4.18 Fri Jul 18 15:02 (00:36)
读者可以看到,使用上述命令显示的信息太多,区分度很小。所以,可以通过指明用户来显示其登录信息即可。例如: 使用last devin来显示devin的历史登录信息,则如下所示:
[root@working]# last devin
devin pts/1 10.0.2.221 Mon Jul 21 15:08 – down (8+17:46)
devin pts/1 10.0.2.221 Mon Jul 21 14:42 – 14:53 (00:11)
ac命令:ac命令根据当前的/var/log/wtmp文件中的登录进入和退出来报告用户连接的时间(小时),如果不使用标志,则报告总的时间。另外,可以加一些参数,例如,last -t 7表示显示上一周的报告。
lastlog命令 lastlog文件在每次有用户登录时被查询。可以使用lastlog命令检查某特定用户上次登录的时间,并格式化输出上次登录日志/var/log/lastlog的内容。它根据UID排序显示登录名、端口号(tty)和上次登录时间。如果一个用户从未登录过,lastlog显示“**Never logged**”。注意需要以root身份运行该命令。运行该命令如下所示:
[root@working]# lastlog
Username Port From Latest
root pts/1 10.0.2.129 二 5月 10 10:13:26 +0800 2005
opal pts/1 10.0.2.129 二 5月 10 10:13:26 +0800 2005
2.使用Syslog设备
Syslog已被许多日志函数采纳,被用在许多保护措施中,任何程序都可以通过syslog 记录事件。Syslog可以记录系统事件,可以写到一个文件或设备中,或给用户发送一个信息。它能记录本地事件或通过网络记录另一个主机上的事件。
Syslog设备核心包括一个守护进程(/etc/syslogd守护进程)和一个配置文件(/etc/syslog.conf配置文件)。通常情况下,多数syslog信息被写到/var/adm或/var/log目录下的信息文件中(messages.*)。一个典型的syslog记录包括生成程序的名字和一个文本信息。它还包括一个设备和一个优先级范围。
系统管理员通过使用syslog.conf文件,可以对生成的日志的位置及其相关信息进行灵活配置,满足应用的需要。例如,如果想把所有邮件消息记录到一个文件中,则做如下操作:
#Log all the mail messages in one place
mail.* /var/log/maillog
其他设备也有自己的日志。UUCP和news设备能产生许多外部消息。它把这些消息存到自己的日志(/var/log/spooler)中并把级别限为\”err\”或更高。例如:
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
当一个紧急消息到来时,可能想让所有的用户都得到。也可能想让自己的日志接收并保存。
#Everybody gets emergency messages, plus log them on anther machine
*.emerg *
*.emerg @linuxaid.com.cn
用户可以在一行中指明所有的设备。下面的例子把info或更高级别的消息送到/var/log/messages,除了mail以外。级别\”none\”禁止一个设备:
#Log anything(except mail)of level info or higher
#Don\&apost log private authentication messages!
*.info:mail.none;autHPriv.none /var/log/messages
在有些情况下,可以把日志送到打印机,这样网络入侵者怎么修改日志都不能清除入侵的痕迹。因此,syslog设备是一个攻击者的显著目标,破坏了它将会使用户很难发现入侵以及入侵的痕迹,因此要特别注意保护其守护进程以及配置文件。
3.程序日志的使用
许多程序通过维护日志来反映系统的安全状态。su命令允许用户获得另一个用户的权限,所以它的安全很重要,它的文件为sulog,同样的还有sudolog。另外,诸如Apache等Http的服务器都有两个日志: access_log(客户端访问日志)以及error_log(服务出错日志)。 FTP服务的日志记录在xferlog文件当中,Linux下邮件传送服务(sendmail)的日志一般存放在maillog文件当中。
程序日志的创建和使用在很大程度上依赖于用户的良好编程习惯。对于一个优秀的程序员来说,任何与系统安全或者网络安全相关的程序的编写,都应该包含日志功能,这样不但便于程序的调试和纠错,而且更重要的是能够给程序的使用方提供日志的分析功能,从而使系统管理员能够较好地掌握程序乃至系统的运行状况和用户的行为,及时采取行动,排除和阻断意外以及恶意的入侵行为。
21
七 05
深夜无眠
深夜醒来,因为胃很难受,昨夜,我喝多了,我又一次冲动致使自己肆意喝酒,酒喝多了,人居然有几分豪气,可惜之后的难楚真是令人难忘。第二次喝成这个样子,凌晨四点多居然胃难受的顶不住,去厕所呕吐了一次刚回来,捧了杯热水,喝上两口,感觉好了一些……
这是我第一次去酒吧,我不肯去,郭晓冬硬把我推进去的,我知道自己不合适那样的环境,怕扫了大家的兴致,但还是面子上挂不住,去了。并且喝了不少酒,以致现在,去吐了一次以后,胃里仍然难受不行。
下午,许子要撤离郑州了,顶着酷暑的天气帮着一起搬运完行李,回到单位发现自己的办公桌居然断掉了,整个桌子都变形了;哎,今天真是运气不佳,发生了不少不愉快的事情,好在现成已经都成为了过去了。
想想,以后自已在郑州真的没有什么人可以找着玩了,熟悉的朋友越来越少,考研的考研,去外地工作的去外地工作。大家都为了生活各自忙各自的事情去了,真正的应了那句话:“人海情海各自游泳”,人天生就是孤独了,我不对友情失望,只是越来越觉得友情珍贵了。
QQ上有人留言,是Jessie,我昨天下午看了《青红》的开始部分,之后接到冬哥的电话便将电影定格,现在居然仍然定位在那里没有移动。我对Jessie说我刚才看《青红》的时候听到熟悉的广播操的播音,心里酸酸的。她说,她刚才去看64运动了……
胃又开始难受了……一阵一阵的。
想想昨天中午的OpenBSD还放在那里,这装还没有进行完,怕许子等着急,就那样放那里便过去帮忙了。许子这个人,挺好,我就是不喜欢他身上的霸气,人可能霸道惯了……
今天一定要把www.bsdmap.com搞好,还有一份维护手册要写,天啊,今天一定会是一个更忙碌的日子!
20
七 05
GNU 编译器家族 GCC 内部探密
GNU 编译器家族 GCC 内部探密 探索 GCC 前端的内部结构
探索 GCC 前端的内部结构
赵蔚 (zhaoway@public1.ptt.js.cn)
Linux 和自由软件技术独立顾问
2003 年 7 月
我们在本文中说明 GCC 源码包中的例子编程语言 Treelang 的实现细节。主要目的在于辑此说明所谓 GCC 前端的编程方法。限于篇幅,本文只能略略讲一下 GCC 前端的内部结构的框架部分。本文中所涉及到的源程序均位于 GCC 源码包中的 gcc/ 目录和 gcc/treelang/ 目录下。本文的代码分析基于 GCC CVS 中的最新(2003 年六月)的开发版本。
GNU 编译器家族 GCC 介绍
作为自由软件的旗舰项目,Richard Stallman 在十多年前刚开始写作 GCC 的时候,还只是把它当作仅仅一个 C 程序语言的编译器;GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言,C++ 语言,Java 语言,Objective C 语言,Pascal 语言,COBOL 语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。
另一方面,说到 GCC 对于各种硬件平台的支持,概括起来就是一句话:无所不在。几乎所有有点实际用途的硬件平台,甚至包括有些不那么有实际用途的硬件平台,比如 Don Knuth 设计的 MMIX 计算机,GCC 都提供了完善的支持。
我们在这篇文章中要弄清楚的就是 GCC 是如何做到能够支持这么多种程序语言的。所谓的 GCC 的程序语言前端到底是怎么回事。如果我们要设计实现自己的编程语言的话,应该从何入手。回答这些问题的第一步,就是分析清楚 GCC 源码包中,为了说明 GCC 的程序语言前端的编写方法,而写作的 Treelang 编程语言在 GCC 中的实现细节。
如果把我们自己的程序语言的实现建立于 GCC 之上,也立刻使得我们的程序语言的实现版本可以运行在几乎所有有用的硬件平台之上。这对于程序语言的作者来说,也是一个确实的有极大诱惑力的好处。
关于代码分析
在这一小节里面我们着重说明两个问题:第一、为什么要阅读源代码;第二、代码分析应该怎么写。
阅读源代码对提高自己的编程水平是非常有帮助的。这个帮助至少体现在两个方面。第一个方面是学会大型软件项目设计的模式。这样的模式是真实可靠的第一手资料,这样学来的模式要比从书本上,用日常语言陈述的模式,更能深入到你的脑海中去。而且它的真实性和可靠性都是有保证的。并且这样的模式还非常的具体。我曾经看到计算机系的同学推荐去读亚历山大的建筑学方面的经典著作;个人以为这是走的太远了。与其去读建筑学的书,不如去分析一下成功的自由软件项目的源代码。具体的用代码说明的模式,无论如何要比虚无飘渺的美学概念,或者模棱两可的工程纪律,都要更加容易学习吧?
阅读源代码的第二个好处,是增加自己的自信心。就象学习英语,要和别人谈话,要看看别人的文章,不能只是看教科书上的简单的例子。教科书上的例子限于篇幅,不可能做到像真实、完整的英文小说那样,把一个完整的设计呈现在你的面前。只有当你硬着头皮,抛开字典,把一本英文小说生生啃下来之后,你才能有把握说:我的确能做到。类似的,只有当我们看过大型软件项目的源代码,作过修改,摸爬滚打之后,我们才能有把握的说:我也能写出来。
上面说了阅读源代码至少有这么两个好处。那么在阅读源代码的时候,我们必然要做代码分析笔记。这个代码分析笔记如何写,这就是我们关心的一个问题了。在这里,我提出一些我自己的也许不太成熟的看法,也请读者朋友们不吝指教。
我总觉得,与其作一行一行的代码注释,说明每一行代码的作用;不如设计一个故事,把代码的框架说清楚。这也是我前面提到的,所谓模式一说。因为阅读源代码,最关键的是要了解大型软件项目设计的模式,而不是要把每一次读者分析每一行代码细节的乐趣从此剥夺掉。
另一方面,代码分析的写作风格,可以是参考手册似的;也可以是航海日志似的。我个人觉得参考手册似的代码分析是比较乏味的,读起来乏味,写起来也不免乏味,虽然它可能更有用。对于一个急着要快点结束加班工作的软件工程师来说,也许参考手册更加实用。但是对于一个想要了解这一份成功的软件背后的工作奥秘的探索者来说,一个航海日志似的代码分析,也许读起来更有味道,更能让一个程序员在键盘与屏幕之间,体会到那地理大发现的激动与乐趣。
本文后面的代码分析,就是希望能写成这样的风格。可是作者笔力有限,如有不足之处,还请读者朋友们不吝指教。
Treelang 的代码框架
读者朋友们在阅读这一部分代码分析的时候,手边最好能准备上一份 GCC 3.3 的源代码。这个源代码可以从 GCC 的站点 http://gcc.gnu.org 上获得。本文作者力图做到把整个情况像说故事一样娓娓道来,但是读者朋友们如果在适当的时候能够查阅一下源代码,可能更能把问题了解的清楚透彻。
这个 treelang 语言的实现,主要有两个 C 语言文件,把整个代码框架分成两个部分。第一部分以 tree1.c 为主,带上 parse.y 这个 YACC 源程序,组成了和 GCC 前端的接口;第二部分以 treetree.c 为主,组成了和 GCC 后端的接口。
这里首先说明一下 tree1.c 这个文件。它和上级目录中的 GCC 框架文件 toplev.c 交互作用,实现 tree1 这个执行程序的主体部分。这个 tree1 就相当于 GCC 的 C 语言前端中的 cc1 执行程序,该程序是 C 语言编译器前端的主体。
我们首先试图说明从 toplev.c 到 tree1.c 的路径。这样我们就注意到 toplev.c 中这个引人注目的 lang_hooks 变量。当然,接下来就注意到在 toplev.c 同一目录下的 langhooks.c 这个文件。我们希望在其中发现一点有趣的东西。这一共是三个文件:langhooks.[ch] 和 langhooks-def.h 其中在 langhooks.h 中定义了一堆各式各样的 struct lang_hooks_for_xxx 结构,以及最后还有一个 struct lang_hooks 结构把前面的那些 for_xxx 的结构都总括了起来。这每一个结构都是若干个至少看上去像是回调函数的函数指针。看来这就是我们要寻找的东西。那么大概就是这样了,编译器前端向 GCC 主体部分注册自己的 lang_hooks 来完成各样的任务。接下来一个自然的问题就是这个注册是如何进行的;另外一个问题就是要对这些回调函数指针进行分析了。
这个 langhooks.h 文件中关于 struct lang_hooks 结构字段的注释很详细,这里我们暂时先跳过去。等到 treelang 中具体的注册回调函数出现的时候,我们根据需要再做仔细说明。在 langhooks-def.h 文件中定义了一些这个 struct lang_hooks 结构的默认值。
现在我们进入 treelang 目录下的 treetree.c 这个文件。来察看一下在 treelang 中对 struct lang_hooks 这个结构的初始化过程。这个过程不是按照我们通常所熟悉的 C 语言的 C99 标准或者是 GCC 扩展语法来进行的。而是采用了大量的 #define 和 #undef 并结合上层目录中的 langhooks-def.h 来进行。细想一下,这是理所当然的事情,因为这是在编译 C 语言编译器本身嘛。当然就不好用到 C 语言的新的东西或者是自己做的扩展的东西。
注释开始:::::
我们以初始化如下定义的 struct sample 结构为例。
struct sample { int member_int; char *member_str; void (*member_fun)(void);};
在 C99 中,初始化一个 struct 结构数据,使用下面这样的语法。
struct sample inst_c99 = { .member_int = 78, .member_str = “iloveqhq”, .member_fun = real_fun,};
在 C99 标准出现之前,GCC 定义了自己的扩展,下面的例子就是按照这个 GCC 对 C 语言的扩展,来初始化一个 struct 结构数据。
struct sample inst_gcc = { member_int: 76, member_str: “zhaoway”, member_fun: real_fun,};
在 GCC 的源代码中没有使用上面的两种办法,而是大量使用了宏定义。这个办法首先要申明一份辅助的宏定义。这些个辅助的宏定义,在一个软件项目里面,针对一个 struct 结构,只需要一份即可。
#define MEMBER_INT 0#define MEMBER_STR “”#define MEMBER_FUN NULL #define SAMPLE_INITIALIZER { \ MEMBER_INT, \ MEMBER_STR, \ MEMBER_FUN, \}
按照上面这样的办法申明了这些关于这个 struct sample 的辅助宏定义以后,在每次要初始化一个 struct sample 数据结构的时候,只需要按照如下操作即可。除了要稍微多打一些字以外,这个方法的方便程度和以上两种方法是差不多的。
#undef MEMBER_INT#define MEMBER_INT 12#undef MEMBER_STR#define MEMBER_STR “trtr”#undef MEMBER_FUN#define MEMBER_FUN real_funstruct sample inst_def = SAMPLE_INITIALIZER;
这样就也可以像 C99 标准或者 GCC 的扩展一样,按照成员变量的名称来初始化一个 struct 类型的数据结构了。不过话又说回来,在我们一般的软件项目中,还是应该沿着 C99 标准这个 C 语言的发展方向来走的。
:::::注释结束
接下来的线路很清楚,就是一个一个的分析这些个回调函数啦。
对用户源文件进行语法分析
这个 treelang 注册的这些回调函数在 GCC 主框架那里被调用的顺序,我们暂时还不想深入。拣有意思的先看看吧。首先关注的是 treelang_parse_file 这个函数。在 langhooks.h 里面关于这个回调函数所作的注释说明,是要它对用户的整个源文件进行语法分析。因为这个函数的返回值是 void 所以我们预期它是通过设置某一个全局变量来完成任务的;但是也有另外一种可能,就是它会把所有要做的事情都给做完,这样它也就自然不需要返回值了。这两种可能我们现在还不能确定。让我们往下看吧。
这个 treelang_parse_file 函数在 tree1.c 中定义,这是属于到 GCC 前端的接口。它直接就跑去调用 yyparse 这个 YACC 主函数了。这倒是简单,呵呵。可是要我们从 parse.y 文件中理出个头绪来,这个文件有超过 900 行的 YACC 代码,未免有点麻烦。最关键的是这中间数据的交流不大容易看清楚,不像回调函数指针这样显而易见。如果程序果真是通过设置一些全局变量来完成任务的话,我们的分析任务就有点棘手了。
注释开始:::::
在这里先说一下 tree 这个数据结构。这是 GCC 围绕着 C 和 C++ 语言的语法分析,用到的主要数据结构。所有其它语言的编译器前端,也都需要在语法分析阶段结束以后,为 GCC 生成相应的 tree 结构的数据。然后 GCC 的后端就可以从 tree 生成独立于平台的 RTL 数据结构,并随后生成相应平台上的机器语言代码。所以作为 GCC 的编译器前端,这里的主要工作就是从一个文本文件,也就是源代码,生成这个 tree 结构的数据,喂给编译器的后端。我们看到,前端是依赖于编程语言的;后端是依赖于机器平台的;中间的 tree 和 RTL 则独立于编程语言和机器平台。但是话虽如此说,这个 tree 和 RTL 数据结构也还是主要以 C 和 C++ 语言为考虑问题的中心。这是不可避免的事情。
:::::注释结束
好啦,没办法啦。我们这就开始从 treelang 目录下的 parse.y 一行一行的往下瞅吧。这个 Treelang 程序语言的语法很简单,我们看到哪儿,说到哪儿。
注释开始:::::
在看 GCC 的源代码的时候经常会遇到 GTY 这个东西。这是 GCC 内部的内存管理机制所需要的,在 C 语言代码上添加的一些类型信息,这些类型信息在 GCC 内部做垃圾收集的时候会用到。这个细节我们这里先忽略过去,以后讲到相关内容的时候再做说明。
:::::注释结束
在 parse.y 中的一些主要的产生式上所匹配的 C 函数,它们所做的工作大体上都是首先根据语法分析的结果,把自己定义的结构 struct prod_token_parm_item 里面的数据先给设置好;然后根据情况调用在 treetree.c 中定义的相关函数,生成 tree 结构的数据;这之后再把返回来的 tree 结构数据记录在 struct prod_token_parm_item 里面,并把整个结构的数据放到 symbol_table 这个单向链表上。这样看来,似乎这个 symbol_table 就是我们前面所要寻找的全局变量了。是不是在语法分析任务完成以后,就获得了这个全局变量;然后依赖于这个全局变量,后续任务才得以获得输入数据,继续往下执行呢?
我们来仔细看一看 tree1.c 中这个 symbol_table 变量的定义如下。
static GTY(()) struct prod_token_parm_item *symbol_table = NULL;
注意到这是被申明为 static 的变量。在 Samuel P. Harbison III 和 Guy L. Steele, Jr 所合著的 C: A Reference Manual 的英文版的第五版第八十三页上,关于 static 变量有如下说明:”On data declarations, it always signifies a defining declaration that is not exported to the linker.”换句话说,这个 static 的 symbol_table 变量,在 tree1.o 之外是看不见的。这不可能是我们所要寻找的全局变量。
可是,另一方面,除了这个变量有点像是那么一回事之外,其它的就再也没有什么有趣的变量了。这是怎么一回事呢?我们先不管它,往下看了再说吧。
那么这个 parse.y 文件大体如是啦。其它的一些具体的细节问题,牵涉到 Treelang 程序语言的具体定义,暂且不是我们的兴趣所在。粗粗的看一遍下来,这个语法分析的过程,从 GCC 的主体结构上,经由 lang_hooks 进入 treelang 部分的 yyparse 函数,这个函数按照语法定义,把编译器用户输入的 Treelang 语言的源程序分解成若干类型的小块,加以分析,生成自己定义的 struct prod_token_parm_item 结构的数据,再把这些数据一个一个串到 symbol_table 这个链表上面;这样就算完成任务了。线索从 lang_hooks 中定义的这个回调函数撤出,再度回到 GCC 的主体框架。
对了,上面还忘了说,在把用户输入的 Treelang 语言的源程序进行分解以后,在分析的过程中,按照各种类型的小块,还生成了相应的 tree 结构的数据,一起记录在各自的 struct prod_token_parm_item 结构里面,这样就一并把这个 tree 结构的数据也都放在了 symbol_table 这个链表里了。
接下来回到 GCC 的主体框架上的 toplev.c 文件。可是迷惑人的事情出现了,在函数 compile_file 对回调函数 treelang_parse_file 进行调用之后,无论是在 toplev.c 文件中,还是说在哪一个其它的回调函数里也好,似乎都并没有什么有趣的事情发生了。这让我们如何是好?看来我们只有回过头去仔细跟踪 treelang 目录下的 treetree.c 文件中的那些函数,看看它们在被 parse.y 中的产生式调用执行的时候,到底干了些什么。
语法分析的细节
根据从 parse.y 这个 YACC 文件中的产生式得来的线索,我们首先关注 treetree.c 文件中的 tree_code_create_variable 这个函数。从那个 YACC 产生式,我们估计这个函数是为一个变量申明而构造必要的 tree 数据结构。这个函数有 100 行不到的源代码。我们来仔细的看一看。这个函数使用了从 GCC 的框架结构里面来的关于 tree 数据结构的一些 API 接口。我们目前所最感兴趣的,就是这个函数在利用这些接口函数构造一个和所对应的 YACC 产生式相当的 tree 结构数据以外,还干了些什么。我们之所以关心这个”以外”,是因为目前我们最想了解的,是这个从 Treelang 语言的源程序开始,到一连串的 tree 结构数据,然后是怎么变成 RTL 结构的数据的。只有在有了这样一个概观以后,我们对 GCC 前端的编写方法才能算有了一个初步的大概的了解。
根据这样的思路,我们很快就看清楚,在这个 tree_code_create_variable 函数中,在设置好若干个局部的 tree 结构的数据以后,引人注目的在一个 if 语句的分支中调用了 rest_of_decl_compilation 这个函数。而且在这个函数被调用返回以后,似乎不再有重要的事情发生了。这个函数来自于 GCC 框架结构上的 toplev.c 文件。这样的话,根据我们前面的分析,这个函数里面应该会隐藏有我们的主要问题的答案。也就是说,在 YACC 文件 parse.y 把用户提供的 Treelang 语言的源文件肢解以后,在 treetree.c 中的相应的函数,为之生成了相应的 tree 结构数据,而在现在我们所关注的这个 rest_of_decl_compilation 函数(以及在这个 if 语句的另一个分支中出现的一系列相应的函数)中,应该会完成从 tree 结构的数据到 RTL 数据的翻译。
从另一个角度补充一点,程序的执行线索是如何从 GCC 主框架进入 parse.y 中的呢?这一段我们前面分析过了,现在再来提醒一下。这是从 GCC 的框架结构,进入到 treelang 这个 GCC 的语言前端模块注册的 lang_hooks 结构的数据,找到相应的回调函数,最终找到 parse.y 这个 YACC 程序的入口 yyparse 函数的。在 yyparse 之后,我们看到程序的主线索进入了 treelang 目录下的 treetree.c 文件中的函数。最后,我们重新又追踪到 GCC 主体部分的 toplev.c 文件中的函数。现在我们的整个图景的大轮廓就快要完全弄清楚了。
GCC 前端的全景图
终于,我们在 rest_of_decl_compilation 函数中,看到了一系列的和 RTL 相关的函数调用。稍微仔细的看了一遍之后,我们有把握得出这个结论了。我们在本文的开头部分,曾经猜想 GCC 的主体部分在要求 GCC 这个 Treelang 语言前端从用户提供的 Treelang 语言的源程序文本,经过语法分析,得出相应的 tree 结构数据以后,会把这个数据通过函数返回值传回给 GCC 的主体程序,或者设置一个全局变量,这样就算完成任务了。但是事实上,经过我们上面的分析,发现不是这么一回事。
相反的,在 Treelang 这个语言前端得到需要的 tree 结构的数据以后,继续往下的运行,这完全是 Treelang 前端必须自己负责的任务。这个 GCC 前端必须自己调用 GCC 主体部分提供的,用来从 tree 结构数据生成 RTL 结构数据的函数接口,以完成从 tree 结构数据到 RTL 结构数据的翻译过程。这样,这个 GCC 的语言前端的任务才算完成。换句话说,GCC 的这个语言前端承担的角色是非常的主动的。很明显,这样的设计提供给我们极大的灵活性。关于这一点,我们以后会逐渐看到。
小结
本文限于篇幅,只大略讲述了 GCC 前端的框架结构,给出了一个粗略的全景图。在以后的几篇文章中,我们将进一步探索 GCC 的主体部分为 GCC 前端所提供的 API 函数和数据结构。并利用这些知识,探索一下为 GCC 编写一个 Scheme 语言前端的可能性。在这一系列文章结束的时候,希望能使得读者朋友们对 GCC 以及程序语言的本质有一个更加深刻的了解。也希望 GCC 的前端的作者人数,就能和 Linux 内核模块的作者人数一样多。我们的座右铭是:每一个人都是程序员;每一个人都能加载自己编写的内核模块;每一个人都能使用自己实现的编程语言!(不要害怕,这只是一句玩笑话。呵呵。)
在技术内容以外,本文也探索了开放源码运动所需要的技术文档的一种写作模式。开放源码运动为我们带来了大量的自由软件的源程序。对于用户来说,需要文档讲述如何使用这些自由软件;对于程序员来说,则需要文档讲述如何才能理解并真正的掌握这些自由软件的源程序。这第二种文档的写作,不是一件容易的事情。作者本人在经常阅读解释自由软件的源程序的内部运作机理的文档的过程中,总是觉得这件事情应该可以有办法做的更好。本文就是作者的一个尝试。希望读者朋友们给我来信,不仅仅讨论 GCC 的技术问题,也欢迎对作者的写作方式提出批评与指教!
参考资料
Internals of the GNU Compiler Collection http://gcc.gnu.org/onlinedocs/gccint/ 这其实也就是 info gccint 的内容。这份文档是除了源代码以外最权威的资料了。不过它的可读性恐怕不是那么好。初上手阅读的时候,恐怕会非常困惑的。
The GNU Treelang Compiler 手册,这其实也就是 info treelang 的内容。这个作为例子的 Treelang 程序语言基于 Tim Josling(见下)为了阐明 GCC 前端的编写方法而发明的一个玩具编程语言。
Sreejith K Menon 编写的 GCC Frontend HOWTO http://www.tldp.org/HOWTO/GCC-Frontend-HOWTO.html 被收录在 The Linux Documentation Project 的 HOWTO 文集中。这份资料可能是可读性最强的了吧?当然,这是说除了本文之外啦。:-)
Using, Maintaining and Enhancing COBOL for the GNU Compiler Collection http://cobolforgcc.sourceforge.net/cobol_toc.html 这是由 Tim Josling 领导的 COBOL for GCC 项目的文档,其中原先由 Joachim Nadler 所编写的第十四章,后来由 Tim Josling 从德文翻译成英文;这一章讲述了 GCC 前端的编写方法。
Using and Porting GNU Fortran 手册 http://gcc.gnu.org/onlinedocs/g77/ 中关于 Front End 的一章也讲述了我们感兴趣的内容。
自由大百科全书 Wikipedia 中关于 GCC 编译器家族的条目 http://www.wikipedia.org/wiki/GNU_Compiler_Collection 对 GCC 有个概括介绍。关于 GCC 内的 RTL 数据结构的条目 http://www.wikipedia.org/wiki/Register_Transfer_Language 以及关于 GCC 的前端使用的 Tree 数据结构的条目 http://www.wikipedia.org/wiki/GCC_Abstract_Syntax_Tree 也都值得一看。
用 Doxygen 文档生成工具制作的 GCC Source Documentation http://www.nondot.org/gcc/ 有兴趣的话也可以看一看。
在阅读大型的 C 语言项目的源代码的时候,手头有一本好的、全的 C 语言参考手册也是很重要的。
关于 C 语言的一本比较好的书是 Samuel P. Harbison III 和 Guy L. Steele, Jr. 合著的 C: A Reference Manual 第五版。这本书的英文影印版最近在国内出版了。作者之一 Guy L. Steele, Jr. 是 Scheme 编程语言的发明人之一,也是 Java 语言规范的作者之一,更是 ACM 的 Grace Murray Hopper 奖 1988 年的获得者。
19
七 05
OpenBSD Tips收集整理
OpenBSD Tips收集整理
Q:网关配制
A:直接将IP写入/etc/mygate
Q:机器名
A:直接写入/etc/myname
Q:网卡配制
A:直接将参数写入/etc/hostname.ifname
比如,网卡名为fxp0则将配制内容:inet 192.168.0.1写入/etc/hostname.fxp0
Q:关闭sendmail
A:将/etc/rc.conf中的sendmail_flags=”xxxx”改为sendmail_falgs=NO
关闭rc.conf中的其它服务方法类似。
Q:重新设置时区:
A:# cd /etc
# ln -s /usr/share/timezone/US/Eastern localtim
Q:如何在OpenBSD下一块网卡绑定多个IP地址!
A:编辑/etc/hostname.dc0 (注意,不同的网卡是不同的名称,我这边是dc0)
#cat /etc/hostname.dc0
inet 192.168.0.2 255.255.255.0 media 100baseTX
inet alias 192.168.0.3 255.255.255.255
inet alias 192.168.0.4 255.255.255.255
现在你知道如何做了吗?
或者通过ifconfig来进行
ifconfig dc0 inet alias 192.168.0.3 netmask 255.255.255.255
Q:查看IP地址的情况!
A:$ ifconfig -A
dc0: flags=8863
media: Ethernet manual
inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
inet 192.168.0.3 netmask 0xffffffff broadcast 192.168.0.3
这个地方一定要使用参数-A
你可以man ifconfig可以看到
If -A is used, it causes full interface alias information for each inter-face to be displayed.
这个参数是用来显示全部接口的alias信息的!
Q:如何使你的OpenBSD支持tab键补齐!
A:到ftp://ftp.openbsd.org/下载一个tcsh-6.12.00-static的package
然后使用pkg_add tcsh-6.12.00-static.tgz
修改/etc/shells
加入
/usr/local/bin/tcsh
执行命令vipw或者chsh修改root的shell为/usr/local/bin/tcsh
注销,重新登陆,你就可以发现你现在的shell可以使用tab键补齐了!
补充:你同样可以使用bash,设置方法同上!
Q:完全关闭sendmail不仅需要
A:将/etc/rc.conf中的sendmail_flags=”xxxx”改为sendmail_falgs=NO
由于系统定时任务还会启动它,所以还需作如下修改
修改/etc/daily
找到下面代码
sh /etc/security 2>&1 > $OUT
if [ -s $OUT ]; then
mail -s “$host daily insecurity output” root < $OUT
fi
修改如下
sh /etc/security 2>&1 > $OUT.TMP
if [ -s $OUT.TMP ]; then
echo “$host daily insecurity output” > $OUT
cat $OUT.TMP >> $OUT
rm $OUT.TMP
/usr/libexec/mail.local root > $OUT
fi
修改crontab
#crontab -u root -e
将
30 1 * * * /bin/sh /etc/daily 2>&1 | tee /var/log/daily.out | mail – s “`/bin/hostname` daily output” root
30 3 * * 6 /bin/sh /etc/weekly 2>&1 | tee /var/log/weekly.out | mail -s “`/bin/hostname` weekly output” root
30 5 1 * * /bin/sh /etc/monthly 2>&1 | tee /var/log/monthly.out | mail -s “`/bin/hostname` monthly output” root
修改为
30 1 * * * /bin/sh /etc/daily 2>&1 | tee /var/log/daily.out | /usr/libexec/mail.local root
30 3 * * 6 /bin/sh /etc/weekly 2>&1 | tee /var/log/weekly.out | /usr/libexec/mail.local root
30 5 1 * * /bin/sh /etc/monthly 2>&1 | tee /var/log/monthly.out | /usr/libexec/mail.local root
并注释掉启动Sendmail行
#*/30 * * * * /usr/sbin/sendmail -L sm-msp-queue -Ac -q
Q:如何让OpenBSD同步网络时间
A:使用命令:
rdate -n time.cn99.com
-n Use SNTP (RFC 1361) instead of the RFC 868 time protocol.
By default, rdate uses the RFC 868 TCP protocol
而在FreeBSD则是用ntpdate来进行时间的同步!
Q:在OpenBSD下通过ftp这个命令来代替fetch的用法!
A”命令的使用格式如下!
ftp -m -V http://apache.linuxforum.net/dist/httpd/apache_1.3.29.tar.gz
这个命令从linuxforum.net的服务器上取得apache_1.3.29.tar.gz这个文件!
如果是从ftp服务器上取得文件,参数相同!
命令参数解释:
-m Causes ftp to always display the progress meter in cases where it
would not do so by default.
-V Disable verbose mode, overriding the default of enabled when in-
put is from a terminal.
Q:如何让OpenBSD关闭并自动关闭电源
A:shutdown -ph now
Q:如何在OpenBSD下面mount .iso文件
A:# mkdir /mnt/iso
# vnconfig svnd0 /home/iso/OpenBSD_3_6.iso
# mount -t cd9660 /dev/svnd0c /mnt/iso
或者:
# mount_cd9660 /dev/svnd0c /mnt/iso
# cd /mnt/iso
Q:如何在OpenBSD下面快速安装package
A:前提:
网络环境,可以连接到Internet,或者你内部有OpenBSD的package的mirror也可以!
设置:
在/root/.cshrc中加入
setenv SITE ftp://ftp5.usa.openbsd.org/pub/OpenBSD/snapshots/packages/i386
上面上我自己使用的设置,你可以根据具体的环境,具体的服务器进行设置。
注销重新登陆使setenv生效。
查找你需要的package
grep packagename /root/mbox
安装package:
pkg_add $SITE/packagename
我的一个例子
OpenBSD[/root]-root->grep cvsup-16.1g mbox
cvsplot-1.6.5.tgz cvsup-16.1g-no_x11.tgz
cvsup-16.1g.tgz cvsupd-16.1g-no_x11.tgz
OpenBSD[/root]-root->pkg_add $SITE/cvsup-16.1g-no_x11.tgz
cvsup-16.1g-no_x11: complete
Q:无安装光盘快速重新安装OpenBSD系统!
A:启动的时候使用boot /bsd.rd
然后安装选择本地硬盘或者通过ftp或者http或者nfs来进行安装,非常方便快捷!
希望FreeBSD也可以做到这样!
19
七 05
FreeBSD下mount总结
FreeBSD下mount总结
13 : 50 FreeBSD下Mount总结!
1.mount FAT/FAT32分区:(C盘为例)
mount -t msdos /dev/ad0s1 /mnt
或
mount_msdos /dev/ad0s1 /mnt for 4.xmount_msdosfs /dev/ad0s1 /mnt for 5.x2.mout Windows的扩展分区(FAT/FAT32):
命令和1一样,只是要记住:扩展分区从s5开始,例如mount D盘,可用:
mount -t msdos /dev/ad0s5 /mnt
mount_msdos /dev/ad0s5 /mnt for 4.x
mount_msdosfs /dev/ad0s5 /mnt for 5.x3.mount NTFS分区:(C盘为例)
mount -t ntfs /dev/ad0s1 /mnt
或
mount_ntfs /dev/ad0s1 /mnt
[注意]1.chinese/gbfs 的 ntfs 似乎有问题,不建议玩家级用户使用注意2.:要让mount上的windows 分区(或CD-ROM)显示中文,需要升级你的ports,再安装gbfs:
#cd /usr/ports/chinese/gbfs
#make install clean
然后编译内核,注释掉options CD9660
options MSDOS注意3.在5.1-current上不用安装gbfs,用:
mount_msdosfs -L zh_CN.GB18030 /dev/ad0sX /mnt
命令就可以支持FAT32分区上的中文文件名,当然,locale可以不用18030,zh_CN.eucCN, zh_CN.GBK都可以!4.mount Linux Ext2fs/Ext3fs:
在内核里面加入options EXT2FS,编译内核。
mount 的时候用mount_ext2fs 命令即可,ext3fs的mount也用mount_ext2fs
5.mount 普通数据光盘:
mount_cd9660 /dev/acd0 /cdrom
6.mount ISO 文件
在5.x中如下
mdconfig -a -t vnode -f abc.iso -u 1
mount_cd9660 /dev/md1 /cdrom4.8的版本
vnconfig /dev/vn0 /home/xiaoche/a.iso
mount -t cd9660 /dev/vn0 /mntumount /mnt
vnconfig -u /dev/vn07.mount CD、VCD、DVD
播放CD、VCD、DVD不用先mount上。
如果你一定要mount上,可以这样:#mount _cd9660 -s 0 /dev/acd0 /cdrom
8.mount 软盘:
1.Format:
# /usr/sbin/fdformat -f 1440 /dev/fd0
2. Run disklabel:
# /sbin/disklabel -B -r -w /dev/fd0 fd1440
3.Create New FS:
# /sbin/newfs_msdos /dev/fd0
4.Mount & Use
#mount_msdosfs /dev/fd0 /mnt
9.mount usb
确保内核中有如下项
device scbus
device da
device cd
在GENERIC中默认都有,如果没有,请编译内核。
大多数U盘用的是FAT 文件系统,所以用
mount -t msdos /dev/da0 /mnt
挂载10.mount ZIP软盘: OneZ 兄提供#mount_msdosfs /dev/afd0s4 /mnt/zip