2010年8月22日

eval

今天看了rc.subr,发现shell的一个用法eval不是很懂,于是在网上查了下,发现一牛人的说法是:
eval执行后面的字符串,这里实际上完成了两命令替换!
上面我理解的意思是:重复执行一行代码两次.

而我看到rc.subr里面的一段代码是

eval _value=\$${1}

会不会是以下的意思呢?
例如${1}是name,那_value就储存$name的值.因为是eval,它执行了\$${1}.也就是先执行了${1}(例如是name),然后再执行\$name, 不过在eval看来,\$被再次执行时就变成了$,也就是变成了$name.

下面一个小脚本可以说明上面我的看法

#!/bin/sh
File="/etc/resolv.conf"
echo "File is \${File}"
eval echo "File is \${File}"

2010年8月20日

lighttpd2

今天来尝下新东西:lighttpd2.0 -- 是一个未开发完整的WEB服务器。

lighttpd2与1.xx首个不同的地方就是配置文件。两种完全不同的配置方式。lighttpd2的配置文件就像一个C语言程序:有函数,要调用已在配置文件中已写的函数才可以远行。有特定的关键字(如一个压缩的函数,我使用了deflate开头并调用,这些会导致lighttpd启动不久后会自己自kill.)它有特定的区域去干特定的事。有些配置信息像varnish(如req.host, req.localip等等).
还有一个有趣的地方就是使用到mod_status这个模块,它会打印出一个人性化的界面,而且您可以自己定义这个界面的,在2里面关于mod_status的配置项只有一个,就不够1.xx丰富了,不知在接下来他们会不会增加一些配置项呢。下面就是使用status的一个生成信息了.

下面是lighttpd1.4.27的status,主要是让它们可以对比一下:
这只是最简单配置后得到的信息。

还有很多很多有趣的事等着我去发掘!

注,status的初始样式都写在mod_status.c源码里面的。

2010年8月19日

今晚做了几件错事

不知是人老啦还是想要睡觉,今晚竟然做了两件错事!

1 安装了logzilla.在网上看到了关于logzilla的介绍,里面说到这个软件可以记录和分析系统的日志,以图形的方式显示出来,可以在任意情况下看到系统的信息.我就安装来玩下,哪知道花了一个晚上的时候搞定了它.不过它弹出来的框雷住了我" 没有flash或者您的flash版本太低" 我真的被吓住了!竟然还得flash才能看啊!不过软件是不会想到我的系统是没有flash的,html5就可以.不过还是算啦吧!等我以后有其它需求时再使用您吧:logzilla!

2 为了logzilla,我把安装来做测试的lighttpd1.5给删除了.我一开始还以为是自己曾经安装varnish作怪,导致在lighttpd无论怎样修改root目录都是显示之前的root目录.然后我就把lighttpd给删除了.对不起啊lighttpd,都怪我没常识把您删除了.原来是我的浏览器缓存在作怪.从现在开始要对自己说:谨用浏览器缓存!

2010年8月18日

用expect给mysql创建用户

之前一直为mysql要创建用户而奔波到去翻mysql手册,现在看来不用了。自己写了一个mysql自己创建用户的expect脚本,那以后就不用那么麻烦了。下面是刚安装完mysql后给它添加root密码和创建新的用户。
代码如下:

#!/usr/local/bin/expect

set timeout 10
set host 172.16.249.126
set password 12345
set user hoho

spawn ssh -l $user -p22 $host
expect "*assword*"
send "$password\n"
sleep 2
spawn mysql -u hohoho -p1234567
expect "mysql>"

send "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '12345678' WITH GRANT OPTION;\n"
send "GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY '12345678' WITH GRANT OPTION;\n"
send "GRANT ALL PRIVILEGES ON *.* TO 'haha'@'localhost' IDENTIFIED BY '12345678' WITH GRANT OPTION;\n"
send "FLUSH PRIVILEGES;\n"
send "GRANT ALL PRIVILEGES ON *.* TO 'haha'@'127.0.0.1' IDENTIFIED BY '12345678' WITH GRANT OPTION;\n"
send "FLUSH PRIVILEGES;\n"
#expect "*OK*"
send "exit\n"
interact

这里就给了mysql创建个一个叫haha的用户,它拥有mysql所有的权限(不过这些可以自己去修改的).我是使用hoho用户去创建的,其中hoho用户也是拥有mysql所有权限的。
详细情况有时候再慢慢调整和做解释。

注:当使用到expect后,当输出的字符符合expect里面内容的话,他就会将send里面的内容显示出来。而不是等到执行时才会进去处理。

2010年8月12日

FreeBSD X不使用hald和dbus

hald使用太多进程了,搞得我看得都烦!于是想把它禁了,在网上看到了可以实现的办法:

1 在/etc/rc.conf里面写入
moused_enable="YES" #在系统启动后就启用mouse.
如果里面有写上hald_enable="YES" 和dbus_enable="YES"那就请注释吧,它们将不会在接下来的top中出现的。

2 在/etc/X11/xorg.conf里面定入

在serverlayout一节中输入:
Option "DontZap" "off"

Option "AllowEmptyInput" "off" #如果启用,就不会增加标准的键盘和mouse驱动。
#如果都没有输入驱动到配置文件,将会使用启用默认配置,如果
#AudoAddDevices和AutoEnableDevices是启用的。那它就不启用。如果
#AllowEmptyInput是启用,那kbd,mouse或者虚拟mouse驱动都会被忽略。

Option "AutoAddDevices" "off" #如果AutoAddDevices是不启用的,当没有驱动时就会从hal事件中增加,启用是使用
#其默认的配置。


完成。

这样当启用X后用top查看,您会看到只多了一个moused进程,那hald*将不会再出现了!

我的N900

很喜欢有键盘手机,因为尝试过全触屏的手机,用起来有点压抑!所以就选择了N900.

N900是的操作系统是maemo,是基于debian的,也就是它也是linux来的,有一个可以拿来玩的terminal。 默认的terminal在输出时是不带色。所以先得给它安装带色的ls,在下面的URL中可以下载
http://www.nitapps.com/dists/chinook/user/binary-armel/color_ls_1.0-1_armel.deb
下载到本地直接使用dpkg -i来安装即可。这里输入ls你会看到色彩的了。

清除其它的locale
清除其它的locale可以给N900省下很多空间(本来N900的rootfs已经很小了)!
只要安装上了localepurge_0.5.8_all.modfied.modfied.deb就可以了,不过在安装上它前必须得先安装两个依赖,分别是
http://repository.maemo.org/pool/maemo4.1.1/free/p/pcre3/libpcre3_6.7-1osso1_armel.deb
http://repository.maemo.org/pool/maemo4.1.1/free/p/pcre3/pcregrep_6.7-1osso1_armel.deb
安装完成就下载localepurge来安装吧
http://forums.internettablettalk.com/attachment.php?attachmentid=2653&d=1225038890
先别急于运行localepurge这个命令,您得先配置/etc/locale.nopurge,这个文件是配置应该去留下哪个locale。你可以增加zh_CN在里面,它默认只留下
en
en_GB
en_US
现在您可以使用localepurge来清除一些locale了。

注: 上面的要下载的软件都可以用命令dpkg -i 来安装。

mysql

今天又学到了一些内容:使用mysql.

一客户他说他的账号和密码登录不了后台,将账号和密码都发过来了测试。然后我只能通过查看mysql关于他的用户名和密码。用到的命令有(我同事帮我搞的,我只在旁边学习)

一个mysql有很多个数据库,他用了一个指令准确找到了很多个数据库中的某个,准确来这算一个模糊查询,就是:

show databases like ‘%database_name%’;

然后通过use database_name来进入这个数据库。

进入后,我的办法呢就是show tables来查看所有的表,然后就用最相似的一个表来查看里面是否有账号密码,语句是select * from table_name;执行后它显示的是一堆占满整个屏幕的数据,看不到哪些是用户名,哪些是密码。而我同事的做法是:先查看这个表的结构 desc table_name;这样可以清楚看到整个表的结构,然后找出username和password字段:select username, password from table_name;这样就可以只看到username和password字段里面的所有数据。

这时我看到了客户提供的用户名和密码,其中密码是使用MD5来加密的。我过去曾在网上用在线MD5解密工具来破解access数据库里面的密码。不过这次就不行了,因为我同事说,之前用到的可以破解的都是原因在这些明文和MD5码都是存放到数据库里面,用查询即可知道MD5码对应的明文。原来这些 MD5是存放在数据库中的,我还以为真的可以破解出来!

quota

今天学到了一个用法:quota的用法。

quota — 磁盘配额的限制。

quota是要先开启才能使用的。它是限制用户使用的多大的空间,超出限额就无法再使用了。目前我的笔记本还没开quota,不过今天在公司搞了一下,到现在还是有一点记忆的,以下的信息都是靠记忆写出来的。

quota [-uvsl] [username]
quota [-gvsl] [groupname]
参数:
-u :后面可以接 username ,表示显示出该使用者磁盘限额的限制值。若不接 username,表示显示出执行者磁盘限额的限制值。
-g :后面可接 groupname ,表示显示出该组的 quota 限制值。
-v :显示每个 filesystem磁盘限额的值;
-s :可选择以inode或磁盘容量的限制值来显示;
-l :仅显示出目前本机上面的filesystem磁盘限额的值。

如quota -uvs 显示当前用户磁盘限额的值

quota -uvs user 显示user磁盘限额的值

修改用户磁盘配额

使用edquota

我对这个命令的理解是使用ed(ed是一个文件编辑器)来编辑quota(磁盘限额),简称edquota.

#edquota –输入后会看到一些内容:下面是内容的解释:

filesystem:代表这个 quota 是针对哪一个分区(如/dev/sda1)的意思。
blocks:这个是目前使用者在这个filesystem,所耗掉的磁盘容量!单位是Mbytes!这个信息是 quota 程序自己计算出来的,所以不要修改他!
soft 与 hard :当soft与hard数值为 0 的时候,表示没有限制!当显示是一些数字,证明这个数据是用户使用磁盘block的最大容量。
inodes:是目前使用掉 inode 的状态,也是 quota 自己计算出来而得到的。最好别修改。当soft与hard数值为 0 的时候,表示没有限制!当显示是一些数字,证明这个数据是用户使用磁盘inode的最大容量。

抄了一个SSH自动登录的脚本

脚本的全部代码如下:

#!/usr/local/bin/expect -f

1 set timeout 30
2 set ssh_host 192.168.1.101
3 spawn ssh -l user -p 22 $ssh_host
4 expect “*assw:”
5 send “password\n”
6 interact

头号“#!/usr/local/bin/expect -f”中的expect是一个交互式对话的实用程序来的,它来源于TCL语言。

1行是设置当您不动这个程序后它会在多少秒里结束对话。

2行是设置ssh_host变量,它的值就是“192.168.1.101”,它也可以用用户输入的地址来作为值:[lindex $argv 0],写法是“set ssh_host [lindex $argv 0]“表示等待用户输入的ssh地址作为参数。它代表着输入程序文件名后的地址。

3行”spawn ssh -l user -p 22 $ssh_host“中的spawn是启动一个新的进程。在这里它是启用了” ssh -l user -p 22 192.168.1.101″这个ssh进程。其中的-l后面带的是login_name,-p后面跟着的就是端口号,再后面就是ssh的地址了。

4行”expect “*password:”终于要开启对话了,当输入ssh -l user -p 22 192.168.1.101后系统会自动弹出对话请求您输入密码。expect就是等待用户的输入,在这里它是等待系统的对话,”*password”是匹配一行中含有password的字符,在对话中,要准确匹配到才会进行正常的对话,要不就会出现问题,也就是说如果系统弹出的对话中只包含有 Password而不是password,那您的这一段代码也就没用了!为了安全起见,我只写了”*assw”,因为我担心系统弹出的是Password 或是passwd那就麻烦了。

5行“send “password\n””是我给系统的回话,说是password\n是我登录ssh的密码,您收到并放行吧。其实send就是用户给系统传送数据的。 \n就是确定的意思。

6行“interact”就是系统和用户开始进行交互式对话吧!

ln

今天差点搞出了一个笑话:

一台邮件服务器存储邮件的那个分区容量满了,是被客户的邮件给挤满的,导致使用WEB登录这台服务器时就出现错误提示而无法登录。而我的解决想法就是做一个链接,在空闲的分区里面新建一个目录,将储存邮件的目录链接到这个目录下,那客户新来的邮件就会走到这个目录上。

我现在想一下,这个想法真的很幼稚很幼稚。原因是我不懂ln的原理造成的。所以今天我要学习ln的用法,以免以后丢自己的脸啊!下面是网络上对ln 的原理的说法:

在存储系统上,一个文件或目录包含在一个 块 集合中。有关文件的信息包含在一个 inode 中,它记录的信息包括所有者、上次访问文件的时间、文件的大小、它是否是一个目录,以及可以对它进行读写操作的对象。inode 号也称为文件序列号,且在特定文件系统内是惟一的。一个目录条目 包含一个文件名或目录名,以及存储有文件或目录相关信息的 inode 的指针。

一个链接 仅仅是文件或目录的一个附加目录条目 (注:就是附加在inode里面),允许同一文件或目录有两个或多个名称。一个硬链接 是指向 inode 的一个目录条目,而一个软链接 或符号链接 是指向提供另一目录条目名称的 inode 的一个目录条目(注:是不是说:硬链接和软链接不同的地方在于硬链接是指向inode的目录条目,而软链接是一个目录条目的inode下的一个目录条目呢?)。存储第二个名称所需的确切机制可能同时取决于文件系统和名称长度。符号链接也称为 symlinks。

您可以仅为文件创建硬链接,而不管目录。例外情况是一个目录中目录本身及其父目录(. 和 ..)的特殊目录条目,它们是保持大量子目录计数的硬链接。由于硬链接指向一个 inode,且 inode 仅在特定文件系统内是惟一的,硬链接不能跨越文件系统。如果一个文件有多个硬链接,仅在指向 inode 的最后一个链接被删除且链接数为 0 时文件才会被删除。

软链接或符号链接仅根据名称(而非 inode)指向另一个文件或目录。软链接可以跨越文件系统界线。删除一个软链接不会删除目标文件或目录,且删除目标文件或目录不会自动删除任何软链接。

而我的同事给我的回答是(他没跟我说上面的这些原理):你可以这样做,不过您又要新建这些客户的邮件目录。
而后来才知道怎样做:先将全部目录都移到新建的链接目录下,链接目录里同时也要新建这些目录。这样是为了不影响到客户的任何数据。当客户打开以前的邮件时系统会自动走到链接目录中寻找邮件。然后再重新建立这些目录,那以后来的邮件又会放到这里,满了再移过链接目录中。

这样做太麻烦了!这个目录有400多G,要每个每个移动是很很很麻烦的。所以目前的解决方法就是删除其它目录下没用的文件以节省空间!

文件描述符

一直不明白文件描述符是什么,今天放下心来看下,终于对文件描述符有所了解:

文件描述符是一个简单的整数,用以标明每一个被进程打开的文件和socket。第一个 打开的文件是0,第二个是1,依此类推。Unix 操作系统通常给每个进程能打开的文件数量强加一个限制

也就是说,UNIX限制了每个进程可以打开多少个文件,文件描述符就是给进程打开的文件打标签,标示着“您啊(指进程),已为打开了这么多的东西, 很快就没得再打开了(指UNIX限制的进程可以开启多少个文件),到时看您怎样再去工作”。
原来进程就如一部电梯,而文件描述符就是电梯的楼层标识。电梯能上得多高看您右手边的楼层按键就知道了。

面试

今天去了一家公司面试,而面试题的最后一道题是:找出Apache的access.log中所有的独立IP,并统计显示出top 10的IP。
而我的做法是:
grep ‘[1,3]\.[1,3]\.[1,3]\.[1,3] | cut -d ‘.’ -f 0-3 | uniq | cat -n 10
而这个写的想法是:用grep算出所有有IP的行,再cut成只有IP,用uniq进行统计, 然后打印出10行。grep暂且不说了,根本就是错的,先来说下uniq吧,我之前还怀疑这个命令是不是用来统计用,刚才查了下资料,才知道uniq是以下的用法:

uniq: 检查及删除文本文件中重复出现的行列。
uniq [-cdu][-f<栏位>][-s<字符位置>][-w<字符位置>][--help][--version] [输入文件][输出文件]
说明:uniq可检查文本文件中重复出现的行列。
参  数:
-c或–count 在每列旁边显示该行重复出现的次数。
-d或 –repeated 仅显示重复出现的行列。
-s<字符位置>或–skip-chars=<字符位置> 忽略比较指定的字符。
-u 或–unique 仅显示出一次的行列。
– n 前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号)。
+n 前n个字符被忽略,之前的字符被跳过(字符从0开始编号)。
 - f n 与- n相同,这里n是字段数。
 - s n 与+n相同,这里n是字符数。
 例子:
 1. 显示文件example中不重复的行。
  uniq – u example
 2. 显示文件example中不重复的行,从第2个字段的第2个字符开始做比较。
  uniq – u – 1 +1 example

而面试官给出的结果是使用sort来进行统计,下面就来说下sort的用法:

sort 命令是对指定的文件中的行进行排序,并将结果写到标准输出。如果指定了多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序。-(减号)代替文件名指定标准输入。如果您不指定任何文件名,那么该命令对标准输入排序。可以使用 -o 标志指定输出文件。

如果不指定任何标志,sort 命令基于当前语言环境的整理顺序对输入文件的所有行排序。

主要参数

-A 使用 ASCII 整理顺序代替当前语言环境的整理顺序在逐字节的基础上排序。
-b 忽略前导空格和制表符,找出字段的第一或最后列。
-c 检查输入是否已按照标志中指定的排序规则进行排序。如果输入文件排序不正确,就返回一个非零值。
-d 使用字典顺序排序。比较中仅考虑字母、数字和空格。
-f 比较前将所有小写字母改成大写字母。
-i 比较中忽略所有非显示字符。
-k KeyDefinition 指定排序关键字。KeyDefinition 选项的格式为: [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]排序关键字包括所有以 FStart 变量指定的字段和 CStart 变量指定的列开头的字符及以 FEnd 变量指定的字段和 CEnd 变量指定的列结束的字符。Modifier 变量的值可以是 b、d、f、i、n 或 r。修饰符与同一字母的标志等价。
-m 只合并多个输入文件;假设输入文件已经排序。
-n 按算术值对数字字段排序。数字字段可包含前导空格、可选减号、十进制数字、千分位分隔符和可选基数符。对包含任何非数字字符的字段进行数字排序会出现无法预知的结果。
-o OutFile 将输出指向 OutFile 参数指定的文件,而不是标准输出。OutFile 参数值可以与 File 参数值相同。
-r 颠倒指定排序的顺序。
-t Character 指定 Character 为单一的字段分隔符。
-u 禁止按照排序关键字和选项的所有等同排序(每一组行中一行除外)。
-T Directory 将创建的所有临时文件放入 Directory 参数指定的目录中。
-y[Kilobytes] 用 Kilobytes 参数指定的主存储的千字节数启动 sort 命令,并根据需要增加存储量。(如果 Kilobytes 参数指定的值小于最小存储站点或大于最大存储站点,就以这个最小存储站点或最大存储站点取代)。如果省略 -y 标志,sort 命令以缺省的存储大小启动。-y0 标志用最小存储启动,而 -y 标志(不带 Kilobytes 值)用最大存储启动。sort 命令使用的存储量显著地影响性能。以大存储量对小文件排序将很浪费。
-z RecordSize 如果正在排序的任一行大于缺省的缓冲区大小,要防止出现异常终止。指定 -c 或 -m 标志时,省略排序阶段,使用系统的缺省缓冲大小。如果已排序行超出这一大小,排序异常终止。-z 选项指定排序阶段最长行的记录,因而可在合并阶段分配足够的缓冲区。RecordSize 必须指明等于或大于要合并的最长行的字节值。

例子
要在 LC_ALL、LC_COLLATE 或 LANG 环境变量设置为 En_US 的情况下排序 fruits 文件,请输入:
LANG=En_US sort fruits此命令序列显示以升序词典顺序排序的 fruits 文件的内容。每一列的字符,包括空格、数字和特殊字符都经一一比较。 例如,如果 fruits 文件包含文本:bananaorangePersimmonapple%%bananaappleORANGEsort 命令显示:%%bananaORANGEPersimmonappleapplebananaorange在 ASCII 整理序列中,%(百分号)在大写字母前,大写字母在小写字母前。如果您当前的语言环境指定 ASCII 之外的字符集,结果可能不同。

要以字典顺序排序,请输入:

sort -d fruits此命令序列排序和显示 fruits 文件的内容,并且只比较字母、数字和空格。如果 fruits 文件与示例 1 相同,那么 sort 命令显示: ORANGEPersimmonappleapple%%bananabananaorange-d 标志忽略 %(百分号)字符,因为它不是个字母、数字或空格。(即 %%banana 被 banana 取代)。

要将包含大写字母和具有类似小写行的特殊字符行分组,请输入:

sort -d -f fruits

-d 标志忽略特殊字符,-f 标志忽略大小写差异。将 LC_ALL、LC_COLLATE 或 LANG 环境变量设置为 C 的情况下,fruits 文件的输出结果变为: appleapple%%bananabananaORANGEorangePersimmon

要除去重复行排序,请输入:

sort -d -f -u fruits

-u 标志告诉 sort 命令除去重复的行,使文件中的每一行唯一。此命令序列显示: apple%%bananaORANGEPersimmon不仅除去重复的 apple,而且也除去了 banana 和 ORANGE。除去这些是因为 -d 标志忽略 %% 这个特殊字符,-f 标志忽略大小写差异。

要如上面那样排序,除去重复的实例(除非是大写字母或标点不同),请输入:

sort -u +0 -d -f +0 fruits输入 +0 -d -f 完成的排序与示例 3 中 -d -f 的排序类型相同,+0 进行另一项比较以区分不一样的行。这防止 -u 标志将它们除去。 示例 1 所示的 fruits 文件中,添加的 +0 将 %%banana 与 banana 及 ORANGE 与 orange 区分开来。然而,apple 的两个实例是相同的,所以其中之一被删除。apple%%bananabananaORANGEorangePersimmon

要指定分隔字段的字符,请输入:

sort -t: +1 vegetables

此命令序列排序 vegetables 文件,对每一行上第一个冒号后的文本进行比较。+1 告诉 sort 命令忽略第一字段,从第二字段的开始到该行的结束进行比较。-t: 标志告诉 sort 命令冒号分隔字段。

如果 vegetables 包含:

yams:104turnips:8potatoes:15carrots:104green beans:32radishes:5lettuce:15那么,将 LC_ALL、LC_COLLATE 或 LANG 环境变量设置为 C 的情况下,sort 命令将显示:carrots:104yams:104lettuce:15potatoes:15green beans:32radishes:5turnips:8注意数字没有按照数字排序。当用字典式分类从左至右比较每一个字符时出现这种情况。换句话说,3 在 5 之前,所以 32 在 5 之前。

要排序数字,请输入:

sort -t: +1 -n vegetables

此命令序列按照第二个字段对 vegetables 文件进行数字排序。如果 vegetables 文件与示例 6 中的相同,那么 sort 命令将显示: radishes:5turnips:8lettuce:15potatoes:15green beans:32carrots:104yams:104

要对多个字段排序,请输入:

sort -t: +1 -2 -n +0 -1 -r vegetables或 sort -t: -k2,2 n -k1,1 r vegetables

此命令序列对第二字段(+1 -2 -n)进行数字排序。在这个顺序中,它以逆字母顺序(+0 -1 -r)对第一字段排序。将 LC_ALL、LC_COLLATE 或 LANG 环境变量设置为 C 的情况下,输出将类似于: radishes:5turnips:8potatoes:15lettuce:15green beans:32yams:104carrots:104

此命令按数字顺序对行排序。当两行数字相同时,它们以逆字母顺序出现。

要使用排序的文本替换原始文件,请输入:

sort -o vegetables vegetables此命令序列将排序输出存入 vegetables 文件( -o vegetables)。

还有就是最后的cat了,面试官的用法就是使用head, 他说cat是无法通过管道进行输出打印的,因些使用了head.

今天真的丢到家了啊!

补: 看了上面的资料后,我得到的修改了答案,下面是答案,主要是修改了最后一部份:
grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' access.log | uniq -cd | sort | head -n 10

希望这次的修改可以减轻我面试过程的错误程度!

注:我今天终于知道怎样去获取一个IP了,现在以用ifconfig 为例吧:
ifconfig re0 | grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} | cut -d ' ' -f 2
or
ifconfig re0 | awk '/inet addr/{ gsub("inet", "", $2); print $2'


grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}这一段主要是检索出有IP的一行。
cut -d ' ' -f 2这里是提取检索出来有IP的一行的第二个字段,也就是IP了。

静态编译和动态编译

这次的面试题还有一个我不懂的题目:静态编译和动态编译的不同。
下面是我找到的关于静态编译和动态编译的好处和坏处:

静态编译
静态函数库的文件后缀名:
这类文件的文件名一般都以 libxxx.a 的类型结尾;

编译过程:
静态编译的函数库在编译时将直接整合到执行文件里面去,所以编译完成后的执行文件会比较大。

静态编译的优点:
它的最大的优点就是编译完成后执行文件可以独立执行而不需要读取其它函数库。

静态编译的缺点:
虽然执行文件可以独立运行,但由于函数库直接整合到执行文件中去了,因些当函数库要升级时,整个执行文件必须要重新编译才可以将新的函数整合到执行文件中。也就是说,在升级过程只,只要函数库升级了,所以整合了这些函数库的执行文件也得要重新编译才行。

动态编译
动态函数库的文件后缀名:
这类文件的文件名一般都以 libxxx.so 的类型结尾;

编译过程:
动态编译和静态编译的差别真的是挺大的。与静态编译不同的是的:在动态编译时,执行文件里面只有一个”指针“而已。也就是说,动态函数库的内容并没有被整合到执行文件中,而是当执行文件被执行到要使用函数库的时候,执行文件才会去读取这些函数库来使用。由于执行文件里面只有一个指针而已,并不包含是函数库的内容,所以动态编译的执行文件会小一点。

动态编译后的执行文件执行过程:
动态编译出来的执行文件是不可以被独立执行的,因为当我们使用动态编译时,程序才会去读取函数库,所以函数库一定要存在才行,而且,函数库所在的目录是不可以改变的,因为动态编译出来可执行文件里面只有指错这东西,一旦这个可执行文件要用到这些函数库时,可执行文件会在指定的路径下读取这些函数库。所以,动态函数库是不可以随便移动或都删除的,这些会影响到依赖这些函数库的程序执行的。

更新方便:
虽然这类型的执行文件无法独立运行,不过由于具有指向功能,所以,当函数库更新后,执行文件根本不需要进行重新编译,因为执行文件会指向这些更新后的函数进行读取(更新后的函数要和更新前的函数相同才行的)。

了解了这些,终于让我知道了为什么有些程序解压后直接运行就可以了。因为它们使用静态编译的方式进行编译的,将函数库都整合在执行文件中了,所以可以立即即行(如Linux下的QQ)。

offset

昨天看到一篇文章,它让我知道了 > 和 >> 的原理:>在文件一开始的地方进行写入,这样会将原文件中所有的字符全部清除,然后再进行写入.而>>就是从文件的末尾进程数据的写 入,这样是在文件的的数据里面再追加内容。(有一个疑点是当文件被进程在使用时,使用>来清空是无法清空的,只会变成>>,也就是追 加。是因为进程在对文件进程操作,也就对文件进程保护,所以无法别人就无法进行清空了。而我就使用了

tail -F 10 /var/log/messages > log.txt 2>&1 &

让tail进程对log.txt文件进行保护,我再用>log.txt却就可以清空log.txt ???)这个不是这次的重点。
看这篇文章让我知道了什么是offset,也是就偏移量。所谓的偏移量就是硬盘中数据在block中的延伸的过程(自己的理解)。这样子就可以想象得到, 使用>是将块的数据给清除掉,然后再对新的数据进行偏移。而 >>就是将位置定在block的后面,然后再进行数据的偏移。
进而再延伸出一个问题:我在freebsdchina.org看到一个帖子,里面的内容是怎样去知道每个进程的IO情况。在FreeBSD可以用 iostat来知道整个硬盘的的IO情况,而无法知道每个进程的IO啊!而我有两个想法:一,可以用lsof来看到每个进程使用的文件描述符去看进程的 IO的情况,不过这种想法有点天真!二:这个想法我觉得是挺靠谱的,用procstat来看到每个进程的IO情况,下面是procstat的一个输出:


PID COMM FD T V FLAGS REF OFFSET PRO NAME
1424 firefox-bin cwd v d ——– – – - /home/minix
1424 firefox-bin root v d ——– – – - /
1424 firefox-bin 0 v c r——- 3 0 – /dev/null
1424 firefox-bin 1 v c rw—— 28 2906 – /dev/ttyv0
1424 firefox-bin 2 v c rw—— 28 2906 – /dev/ttyv0
1424 firefox-bin 3 s – rw—n– 1 0 UDS /tmp/.X11-unix/X0
1424 firefox-bin 4 p – rw—— 1 0 – –
1424 firefox-bin 5 p – rw—— 1 0 – –
1424 firefox-bin 6 p – rw—— 1 0 – –
1424 firefox-bin 7 p – rw—— 1 0 – –
1424 firefox-bin 8 p – rw—— 1 0 – –
1424 firefox-bin 9 p – rw—n– 1 0 – –
1424 firefox-bin 10 s – rw—n– 1 0 UDS /var/tmp/dbus-kM0HYCdoTc
1424 firefox-bin 11 s – rw—n– 1 0 UDS /var/tmp/orbit-minix/linc-593-0-532e348f96d8e
1424 firefox-bin 12 s – rw—n– 1 0 UDS /var/tmp/orbit-minix/linc-590-0-44c8bb0badd77
1424 firefox-bin 13 s – rw—n– 1 0 UDS /var/tmp/orbit-minix/linc-590-0-44c8bb0badd77
1424 firefox-bin 14 v r -w—— 1 0 – /home/minix/.mozilla/firefox/fchaa7jx.default/.parentlock
1424 firefox-bin 15 p – rw—n– 1 0 – –
1424 firefox-bin 16 p – rw—n– 1 0 – –
1424 firefox-bin 17 p – rw—n– 1 0 – –
1424 firefox-bin 18 p – rw—n– 1 0 – –
1424 firefox-bin 19 v c r——- 1 4 – /dev/random
1424 firefox-bin 20 s – rw—n– 1 0 TCP 127.0.0.1:36520 127.0.0.1:80
1424 firefox-bin 21 v r r——- 1 0 – /usr/local/lib/firefox3/chrome/en-US.jar
1424 firefox-bin 22 v r rw—— 1 2048 – /home/minix/.mozilla/firefox/fchaa7jx.default/permissions.sqlite
1424 firefox-bin 23 v r r——- 1 0 – /usr/local/lib/firefox3/chrome/browser.jar
1424 firefox-bin 24 v r r——- 1 0 – /home/minix/.mozilla/firefox/fchaa7jx.default/extensions/chromifox@altmusictv.com/chrome/chromifox.jar
1424 firefox-bin 25 v r r——- 1 0 – /usr/local/lib/firefox3/chrome/toolkit.jar
1424 firefox-bin 26 v r rw—— 1 1343488 – /home/minix/.mozilla/firefox/fchaa7jx.default/places.sqlite
1424 firefox-bin 27 v r r——- 1 1023273 – /home/minix/.mozilla/firefox/fchaa7jx.default/XUL.mfasl
1424 firefox-bin 28 v r r——- 1 0 – /home/minix/.mozilla/firefox/fchaa7jx.default/extensions/vimperator@mozdev.org/chrome/vimperator.jar
1424 firefox-bin 29 v r rw—— 1 40 – /home/minix/.mozilla/firefox/fchaa7jx.default/search.sqlite
1424 firefox-bin 30 v r rw—— 1 40 – /home/minix/.mozilla/firefox/fchaa7jx.default/content-prefs.sqlite
1424 firefox-bin 31 v r rw—— 1 40 – /home/minix/.mozilla/firefox/fchaa7jx.default/formhistory.sqlite
1424 firefox-bin 32 s – rw—n– 1 0 TCP 192.168.0.101:27176 72.14.203.18:443
1424 firefox-bin 33 v r rw—— 1 12460032 – /home/minix/.mozilla/firefox/fchaa7jx.default/urlclassifier3.sqlite
1424 firefox-bin 34 v r rw—— 1 81920 – /home/minix/.mozilla/firefox/fchaa7jx.default/cookies.sqlite
1424 firefox-bin 35 v r rw—— 1 28 – –
1424 firefox-bin 36 v d r——- 1 0 – /home/minix/.mozilla/firefox/fchaa7jx.default
1424 firefox-bin 37 v r rw—— 1 276 – /home/minix/.mozilla/firefox/fchaa7jx.default/Cache/_CACHE_MAP_
1424 firefox-bin 38 v r rw—— 1 94047 – /home/minix/.mozilla/firefox/fchaa7jx.default/Cache/_CACHE_001_
1424 firefox-bin 39 v r rw—— 1 197710 – /home/minix/.mozilla/firefox/fchaa7jx.default/Cache/_CACHE_002_
1424 firefox-bin 40 v r rw—— 1 311987 – /home/minix/.mozilla/firefox/fchaa7jx.default/Cache/_CACHE_003_
1424 firefox-bin 41 v r rw—— 1 260 – /home/minix/.mozilla/firefox/fchaa7jx.default/cert8.db
1424 firefox-bin 42 v r rw—— 1 260 – /home/minix/.mozilla/firefox/fchaa7jx.default/key3.db
1424 firefox-bin 43 p – rw—n– 1 0 – –
1424 firefox-bin 44 p – rw—n– 1 0 – –
1424 firefox-bin 45 s – rw—n– 1 0 TCP 192.168.0.101:57098 74.125.153.83:443
1424 firefox-bin 46 v r rw—— 1 40 – /home/minix/.mozilla/firefox/fchaa7jx.default/downloads.sqlite
1424 firefox-bin 49 v r rw—— 1 40 – /home/minix/.mozilla/firefox/fchaa7jx.default/signons.sqlite
1424 firefox-bin 55 v r rw—— 1 512 – /home/minix/.mozilla/firefox/fchaa7jx.default/places.sqlite-journal

从这里来看下offset一行,会看到一个进程对文件的操作,数据的大小可以看到它的IO情况了。

一个错误的shell script

错误的script:

#!/bin/sh

PROFILE="/home/minix/local/lighttpd/etc/lighttpd.conf"
BINFILE="/home/minix/local/lighttpd/sbin/lighttpd"
PORT=`sockstat -4l | grep 80`

if [ -x ${BINFILE} ] && [ ${PORT} == "" ]
then
if [ -f ${PROFILE} ]
then
sudo ${BINFILE} -f ${PROFILE} & sleep 2 echo "success !! "
exit 0
else
echo " File Don't exist! \n" exit 1
fi
else
echo "haha, file ${BINFILE} don't execute Or 80 port using, please check file and port "
exit 2
fi

下面是修改正确后的script

#!/bin/sh

PROFILE="/home/minix/local/lighttpd/etc/lighttpd.conf"
BINFILE="/home/minix/local/lighttpd/sbin/lighttpd"
PORT=`sockstat -4l | grep 80`

if [ -x ${BINFILE} ] && [ -z ${PORT} ]
then
if [ -f ${PROFILE} ]
then
sudo ${BINFILE} -f ${PROFILE} &
sleep 2
echo "success !! "
exit 0
else
echo " File Don't exist! \n"
exit 1
fi
else
echo "haha, file ${BINFILE} don't execute Or 80 port using, please check file and port "
exit 2
fi

记下来,当作自己的脚印!