ラベル linux の投稿を表示しています。 すべての投稿を表示
ラベル linux の投稿を表示しています。 すべての投稿を表示

2010年7月28日水曜日

ubuntu下的WPA无线网络配置

安装好网卡后,安装 (最新版Ubuntu Server 10.04已集成wpasupplicant)
apt-get install wpasupplicant

生成配置文件:
wpa_passphrase YOUR_SSID YOUR_KEY > /etc/wpa_supplicant.conf

修改/etc/network/interfaces:
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant.conf


(/etc/wpa_supplicant.conf 这个位置可以随便定)

2010年4月16日金曜日

不同的类UNIX操作系统密码破解方法介绍

(一)Linux 系统密码破解

1.在grub选项菜单按E进入编辑模式

2.编辑kernel那行 /init 1 (或/single)

3.按B重启

4.进入后执行下列命令

root@#passwd root (设置root的密码)

Enter new unix password:输入新的密码

root@#init 6



(二)debian linux 系统密码破解

1.在grub选项菜单'Debian GNU/Linux,...(recovery mode)',按e进入编辑模式

2.编辑kernel那行最后面的 ro single 改成 rw single init=/bin/bash,按b执行重启

3.进入后执行下列命令

root@(none)#mount -a

root@(none)#passwd root

root@(none)#reboot



(三)Freebsd 系统密码破解

1.开机进入引导菜单

2.选择每项(按4)进入单用户模式

3.进入之后输入一列命令

root@#mount -a

root@#fsck -y

root@#passwd(修改密码命令)

root@#root(要破解密码的用户名)

Enter new unix password:

root@#init 6 (重启)



(四)Solaris 系统密码破解

1.在grub选项菜中选择solaris failasfe 项

2.系统提示Do you wish to have it mounted read-write on /a ?[y,n,?] 选择y

3.就进入单用户模式

4.输入下列命令

#passwd

#New passwd:输入新的密码

#Re-enter New passwd:在次输入新的密码

#init 6 (重启)



(五)NetBsd 系统密码破解

1.开机:当出现提示符号并开始倒数五秒时, 键入以下指令:

> boot -s (进入单用户模式命令)

2.在以下的提示符号中

Enter pathname of shell or RETURN for sh:

按下 Enter。

3.键入以下指令:

# mount -a

# fsck -y

4.使用 passwd 更改 root 的密码。

5.使用 exit 指令进入多人模式。

2009年12月20日日曜日

我的Linux常用软件(随时更新)

Ubuntu9.1安装完成后,又安装了以下软件。
记录下来,下次重装系统的时候用。
  1. aMSN
  2. 腾讯QQ For Linux
  3. Skype
  4. Audacious2
  5. MPlayer(SMPlayer)
  6. GVim
  7. EasyTAG
  8. 7zip
  9. unrar

2009年12月9日水曜日

《SED 单行脚本快速参考》的 awk 实现

{ 撰文/bones7456 }

sed 和 awk 都是 Linux 下常用的流编辑器,他们各有各的特色,本文并不是要做什么对比,而是权当好玩,把《SED 单行脚本快速参考》这文章,用 awk 做了一遍~ 至于孰好孰坏,那真是很难评论了。一般来说,sed 的命令会更短小一些,同时也更难读懂;而 awk 稍微长点,但是 if、while 这样的,逻辑性比较强,更加像“程序”。到底喜欢用哪个,就让各位看官自己决定吧!

文本间隔:

# 在每一行后面增加一空行

sed G
awk '{printf("%s\n\n",$0)}'

# 将原来的所有空行删除并在每一行后面增加一空行。
# 这样在输出的文本中每一行后面将有且只有一空行。

sed '/^$/d;G'
awk '!/^$/{printf("%s\n\n",$0)}'

# 在每一行后面增加两行空行

sed 'G;G'
awk '{printf("%s\n\n\n",$0)}'

# 将第一个脚本所产生的所有空行删除(即删除所有偶数行)

sed 'n;d'
awk '{f=!f;if(f)print $0}'

# 在匹配式样“regex”的行之前插入一空行

sed '/regex/{x;p;x;}'
awk '{if(/regex/)printf("\n%s\n",$0);else print $0}'

# 在匹配式样“regex”的行之后插入一空行

sed '/regex/G'
awk '{if(/regex/)printf("%s\n\n",$0);else print $0}'

# 在匹配式样“regex”的行之前和之后各插入一空行

sed '/regex/{x;p;x;G;}'
awk '{if(/regex/)printf("\n%s\n\n",$0);else print $0}'

编号:

# 为文件中的每一行进行编号(简单的左对齐方式)。这里使用了“制表符”
# (tab,见本文末尾关于’\t’的用法的描述)而不是空格来对齐边缘。

sed = filename | sed 'N;s/\n/\t/'
awk '{i++;printf("%d\t%s\n",i,$0)}'

# 对文件中的所有行编号(行号在左,文字右端对齐)。

sed = filename | sed 'N; s/^/     /; s/ *\(.\{6,\}\)\n/\1  /'
awk '{i++;printf("%6d %s\n",i,$0)}'

# 对文件中的所有行编号,但只显示非空白行的行号。

sed '/./=' filename | sed '/./N; s/\n/ /'
awk '{i++;if(!/^$/)printf("%d %s\n",i,$0);else print}'

# 计算行数 (模拟 “wc -l”)

sed -n '$='
awk '{i++}END{print i}'

文本转换和替代:

# Unix环境:转换DOS的新行符(CR/LF)为Unix格式。

sed 's/.$//'                     # 假设所有行以CR/LF结束
sed 's/^M$//' # 在bash/tcsh中,将按Ctrl-M改为按Ctrl-V
sed 's/\x0D$//' # ssed、gsed 3.02.80,及更高版本
awk '{sub(/\x0D$/,"");print $0}'

# Unix环境:转换Unix的新行符(LF)为DOS格式。

sed "s/$/`echo -e \\\r`/"        # 在ksh下所使用的命令
sed 's/$'"/`echo \\\r`/" # 在bash下所使用的命令
sed "s/$/`echo \\\r`/" # 在zsh下所使用的命令
sed 's/$/\r/' # gsed 3.02.80 及更高版本
awk '{printf("%s\r\n",$0)}'

# DOS环境:转换Unix新行符(LF)为DOS格式。

sed "s/$//"                      # 方法 1
sed -n p # 方法 2

DOS环境的略过

# DOS环境:转换DOS新行符(CR/LF)为Unix格式。
# 下面的脚本只对UnxUtils sed 4.0.7 及更高版本有效。要识别UnxUtils版本的
# sed可以通过其特有的“–text”选项。你可以使用帮助选项(“–help”)看
# 其中有无一个“–text”项以此来判断所使用的是否是UnxUtils版本。其它DOS
# 版本的的sed则无法进行这一转换。但可以用“tr”来实现这一转换。

sed "s/\r//" infile >outfile     # UnxUtils sed v4.0.7 或更高版本
tr -d \r outfile # GNU tr 1.22 或更高版本

DOS环境的略过

# 将每一行前导的“空白字符”(空格,制表符)删除
# 使之左对齐

sed 's/^[ \t]*//'                # 见本文末尾关于'\t'用法的描述
awk '{sub(/^[ \t]+/,"");print $0}'

# 将每一行拖尾的“空白字符”(空格,制表符)删除

sed 's/[ \t]*$//'                # 见本文末尾关于'\t'用法的描述
awk '{sub(/[ \t]+$/,"");print $0}'

# 将每一行中的前导和拖尾的空白字符删除

sed 's/^[ \t]*//;s/[ \t]*$//'
awk '{sub(/^[ \t]+/,"");sub(/[ \t]+$/,"");print $0}'

# 在每一行开头处插入5个空格(使全文向右移动5个字符的位置)

sed 's/^/     /'
awk '{printf(" %s\n",$0)}'

# 以79个字符为宽度,将所有文本右对齐
# 78个字符外加最后的一个空格

sed -e :a -e 's/^.\{1,78\}$/ &/;ta'
awk '{printf("%79s\n",$0)}'

# 以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前
# 头和后头都填充了空格。 在方法2中,在居中文本的过程中只在文本的前面填充
# 空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格。

sed  -e :a -e 's/^.\{1,77\}$/ & /;ta'                     # 方法1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # 方法2
awk '{for(i=0;i<39-length($0)/2;i++)printf(">

# 在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”

sed 's/foo/bar/'                 # 只替换每一行中的第一个“foo”字串
sed 's/foo/bar/4' # 只替换每一行中的第四个“foo”字串
sed 's/foo/bar/g' # 将每一行中的所有“foo”都换成“bar”
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替换倒数第二个“foo”
sed 's/\(.*\)foo/\1bar/' # 替换最后一个“foo”
awk '{gsub(/foo/,"bar");print $0}' # 将每一行中的所有“foo”都换成“bar”

# 只在行中出现字串“baz”的情况下将“foo”替换成“bar”

sed '/baz/s/foo/bar/g'
awk '{if(/baz/)gsub(/foo/,"bar");print $0}'

# 将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换

sed '/baz/!s/foo/bar/g'
awk '{if(/baz$/)gsub(/foo/,"bar");print $0}'

# 不管是“scarlet”“ruby”还是“puce”,一律换成“red”

sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'  #对多数的sed都有效
gsed 's/scarlet\|ruby\|puce/red/g' # 只对GNU sed有效
awk '{gsub(/scarlet|ruby|puce/,"red");print $0}'

# 倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)。
# 由于某些原因,使用下面命令时HHsed v1.5会将文件中的空行删除

sed '1!G;h;$!d'               # 方法1
sed -n '1!G;h;$p' # 方法2
awk '{A[i++]=$0}END{for(j=i-1;j>=0;j--)print A[j]}'

# 将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)

sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
awk '{for(i=length($0);i>0;i--)printf("%s",substr($0,i,1));printf("\n")}'

# 将每两行连接成一行(类似“paste”)

sed '$!N;s/\n/ /'
awk '{f=!f;if(f)printf("%s",$0);else printf(" %s\n",$0)}'

# 如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾
# 并去掉原来行尾的反斜杠

sed -e :a -e '/\\$/N; s/\\\n//; ta'
awk '{if(/\\$/)printf("%s",substr($0,0,length($0)-1));else printf("%s\n",$0)}'

# 如果当前行以等号开头,将当前行并到上一行末尾
# 并以单个空格代替原来行头的“=”

sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
awk '{if(/^=/)printf(" %s",substr($0,2));else printf("%s%s",a,$0);a="\n"}END{printf("\n")}'

# 为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”

gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta'                     # GNU sed
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # 其他sed

#awk的正则没有后向匹配和引用,搞的比较狼狈,呵呵。

awk '{while(match($0,/[0-9][0-9][0-9][0-9]+/)){$0=sprintf("%s,%s",substr($0,0,RSTART+RLENGTH-4),substr($0,RSTART+RLENGTH-3))}print $0}'

# 为带有小数点和负号的数值增加逗号分隔符(GNU sed)

gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'

#和上例差不多

awk '{while(match($0,/[^\.0-9][0-9][0-9][0-9][0-9]+/)){$0=sprintf("%s,%s",substr($0,0,RSTART+RLENGTH-4),substr($0,RSTART+RLENGTH-3))}print $0}'

# 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)

gsed '0~5G'                      # 只对GNU sed有效
sed 'n;n;n;n;G;' # 其他sed
awk '{print $0;i++;if(i==5){printf("\n");i=0}}'

选择性地显示特定行:

# 显示文件中的前10行 (模拟“head”的行为)

sed 10q
awk '{print;if(NR==10)exit}'

# 显示文件中的第一行 (模拟“head -1”命令)

sed q
awk '{print;exit}'

# 显示文件中的最后10行 (模拟“tail”)

sed -e :a -e '$q;N;11,$D;ba'

#用awk干这个有点亏,得全文缓存,对于大文件肯定很慢

awk '{A[NR]=$0}END{for(i=NR-9;i<=NR;i++)print A[i]}' 

# 显示文件中的最后2行(模拟“tail -2”命令)

sed '$!N;$!D'
awk '{A[NR]=$0}END{for(i=NR-1;i<=NR;i++)print A[i]}'

# 显示文件中的最后一行(模拟“tail -1”)

sed '$!d'                        # 方法1
sed -n '$p' # 方法2

#这个比较好办,只存最后一行了。

awk '{A=$0}END{print A}'

# 显示文件中的倒数第二行

sed -e '$!{h;d;}' -e x              # 当文件中只有一行时,输出空行
sed -e '1{$q;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,显示该行
sed -e '1{$d;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,不输出

#存两行呗(当文件中只有一行时,输出空行)

awk '{B=A;A=$0}END{print B}'

# 只显示匹配正则表达式的行(模拟“grep”)

sed -n '/regexp/p'               # 方法1
sed '/regexp/!d' # 方法2
awk '/regexp/{print}'

# 只显示“不”匹配正则表达式的行(模拟“grep -v”)

sed -n '/regexp/!p'              # 方法1,与前面的命令相对应
sed '/regexp/d' # 方法2,类似的语法
awk '!/regexp/{print}'

# 查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行

sed -n '/regexp/{g;1!p;};h'
awk '/regexp/{print A}{A=$0}'

# 查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行

sed -n '/regexp/{n;p;}'
awk '{if(A)print;A=0}/regexp/{A=1}'

# 显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1 -B1”)

sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
awk '{if(F)print;F=0}/regexp/{print NR;print b;print;F=1}{b=$0}'

# 显示包含“AAA”、“BBB”和“CCC”的行(任意次序)

sed '/AAA/!d; /BBB/!d; /CCC/!d'   # 字串的次序不影响结果
awk '{if(match($0,/AAA/) && match($0,/BBB/) && match($0,/CCC/))print}'

# 显示包含“AAA”、“BBB”和“CCC”的行(固定次序)

sed '/AAA.*BBB.*CCC/!d'
awk '{if(match($0,/AAA.*BBB.*CCC/))print}'

# 显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)

sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d    # 多数sed
gsed '/AAA\|BBB\|CCC/!d' # 对GNU sed有效
awk '/AAA/{print;next}/BBB/{print;next}/CCC/{print}'
awk '/AAA|BBB|CCC/{print}'

# 显示包含“AAA”的段落 (段落间以空行分隔)
# HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样

sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
awk 'BEGIN{RS=""}/AAA/{print}'
awk -vRS= '/AAA/{print}'

# 显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)

sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
awk -vRS= '{if(match($0,/AAA/) && match($0,/BBB/) && match($0,/CCC/))print}'

# 显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)

sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # 只对GNU sed有效
awk -vRS= '/AAA|BBB|CCC/{print "";print}'

# 显示包含65个或以上字符的行

sed -n '/^.\{65\}/p'

cat ll.txt | awk '{if(length($0)>=65)print}'

# 显示包含65个以下字符的行

sed -n '/^.\{65\}/!p'            # 方法1,与上面的脚本相对应
sed '/^.\{65\}/d' # 方法2,更简便一点的方法
awk '{if(length($0)<=65)print}'

# 显示部分文本——从包含正则表达式的行开始到最后一行结束

sed -n '/regexp/,$p'
awk '/regexp/{F=1}{if(F)print}'

# 显示部分文本——指定行号范围(从第8至第12行,含8和12行)

sed -n '8,12p'                   # 方法1
sed '8,12!d' # 方法2
awk '{if(NR>=8 && NR<12)print}'>

# 显示第52行

sed -n '52p'                     # 方法1
sed '52!d' # 方法2
sed '52q;d' # 方法3, 处理大文件时更有效率
awk '{if(NR==52){print;exit}}'

# 从第3行开始,每7行显示一次

gsed -n '3~7p'                   # 只对GNU sed有效
sed -n '3,${p;n;n;n;n;n;n;}' # 其他sed
awk '{if(NR==3)F=1}{if(F){i++;if(i%7==1)print}}'

# 显示两个正则表达式之间的文本(包含)

sed -n '/Iowa/,/Montana/p'       # 区分大小写方式
awk '/Iowa/{F=1}{if(F)print}/Montana/{F=0}'

选择性地删除特定行:

# 显示通篇文档,除了两个正则表达式之间的内容

sed '/Iowa/,/Montana/d'
awk '/Iowa/{F=1}{if(!F)print}/Montana/{F=0}'

# 删除文件中相邻的重复行(模拟“uniq”)
# 只保留重复行中的第一行,其他行删除

sed '$!N; /^\(.*\)\n\1$/!P; D'
awk '{if($0!=B)print;B=$0}'

# 删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存大小,或者使用GNU sed。

sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'  #bones7456注:我这里此命令并不能正常工作
awk '{if(!($0 in B))print;B[$0]=1}'

# 删除除重复行外的所有行(模拟“uniq -d”)

sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'
awk '{if($0==B && $0!=l){print;l=$0}B=$0}'

# 删除文件中开头的10行

sed '1,10d'
awk '{if(NR>10)print}'

# 删除文件中的最后一行

sed '$d'

#awk在过程中并不知道文件一共有几行,所以只能通篇缓存,大文件可能不适合,下面两个也一样

awk '{B[NR]=$0}END{for(i=0;i<=NR-1;i++)print B[i]}' 

# 删除文件中的最后两行

sed 'N;$!P;$!D;$d'
awk '{B[NR]=$0}END{for(i=0;i<=NR-2;i++)print B[i]}'

# 删除文件中的最后10行

sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # 方法1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # 方法2
awk '{B[NR]=$0}END{for(i=0;i<=NR-10;i++)print B[i]}'

# 删除8的倍数行

gsed '0~8d'                           # 只对GNU sed有效
sed 'n;n;n;n;n;n;n;d;' # 其他sed
awk '{if(NR%8!=0)print}' |head

# 删除匹配式样的行

sed '/pattern/d'                      # 删除含pattern的行。当然pattern可以换成任何有效的正则表达式
awk '{if(!match($0,/pattern/))print}'

# 删除文件中的所有空行(与“grep ‘.’ ”效果相同)

sed '/^$/d'                           # 方法1
sed '/./!d' # 方法2
awk '{if(!match($0,/^$/))print}'

# 只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。
# (模拟“cat -s”)

sed '/./,/^$/!d'        #方法1,删除文件顶部的空行,允许尾部保留一空行
sed '/^$/N;/\n$/D' #方法2,允许顶部保留一空行,尾部不留空行
awk '{if(!match($0,/^$/)){print;F=1}else{if(F)print;F=0}}' #同上面的方法2

# 只保留多个相邻空行的前两行。

sed '/^$/N;/\n$/N;//D'
awk '{if(!match($0,/^$/)){print;F=0}else{if(F<2)print;f++}}'>

# 删除文件顶部的所有空行

sed '/./,$!d'
awk '{if(F || !match($0,/^$/)){print;F=1}}'

# 删除文件尾部的所有空行

sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'  # 对所有sed有效
sed -e :a -e '/^\n*$/N;/\n$/ba' # 同上,但只对 gsed 3.02.*有效
awk '/^.+$/{for(i=l;i

# 删除每个段落的最后一行

sed -n '/^$/{p;h;};/./{x;/./p;}'

#很长,很ugly,应该有更好的办法

awk -vRS= '{B=$0;l=0;f=1;while(match(B,/\n/)>0){print substr(B,l,RSTART-l-f);l=RSTART;sub(/\n/,"",B);f=0};print ""}'

特殊应用:

# 移除手册页(man page)中的nroff标记。在Unix System V或bash shell下使
# 用’echo’命令时可能需要加上 -e 选项。

sed "s/.`echo \\\b`//g"    # 外层的双括号是必须的(Unix环境)
sed 's/.^H//g' # 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
sed 's/.\x08//g' # sed 1.5,GNU sed,ssed所使用的十六进制的表示方法
awk '{gsub(/.\x08/,"",$0);print}'

# 提取新闻组或 e-mail 的邮件头

sed '/^$/q'                # 删除第一行空行后的所有内容
awk '{print}/^$/{exit}'

# 提取新闻组或 e-mail 的正文部分

sed '1,/^$/d'              # 删除第一行空行之前的所有内容
awk '{if(F)print}/^$/{F=1}'

# 从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样

sed '/^Subject: */!d; s///;q'
awk '/^Subject:.*/{print substr($0,10)}/^$/{exit}'

# 从邮件头获得回复地址

sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

#好像是输出第一个Reply-To:开头的行?From是干啥用的?不清楚规则。。

awk '/^Reply-To:.*/{print;exit}/^$/{exit}'

# 获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除。(见上一脚本)

sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//' 

#取尖括号里的东西吧?

awk -F'[<>]+' '{print $2}'

# 在每一行开头加上一个尖括号和空格(引用信息)

sed 's/^/> /'
awk '{print "> " $0}'

# 将每一行开头处的尖括号和空格删除(解除引用)

sed 's/^> //'
awk '/^> /{print substr($0,3)}'

# 移除大部分的HTML标签(包括跨行标签)

sed -e :a -e 's/<[^>]*>//g;/<[^>]*>/,"",$0);print}'

# 将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分。
# 文件必须以特定顺序传给sed。下面第一种版本的脚本可以直接在命令行下输入;
# 第二种版本则可以放入一个带执行权限的shell脚本中。(由Rahul Dhesi的一
# 个脚本修改而来。)

sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode   # vers. 1
sed '/^end/,/^begin/d' "$@" | uudecode # vers. 2

#我不想装个uudecode验证,大致写个吧

awk '/^end/{F=0}{if(F)print}/^begin/{F=1}' file1 file2 ... fileX

# 将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU sed使用
# 字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以
# 用其他未在文件中使用的字符来代替它。

sed '/./{H;d;};x;s/\n/={NL}=/g' file | sort | sed '1s/={NL}=//;s/={NL}=/\n/g'
gsed '/./{H;d};x;y/\n/\v/' file | sort | sed '1s/\v//;y/\v/\n/'
awk -vRS= '{gsub(/\n/,"\v",$0);print}' ll.txt | sort | awk '{gsub(/\v/,"\n",$0);print;print ""}'

# 分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件
# 命名为与原来相同的名字(只是扩展名不同)。(DOS环境:“dir /b”
# 显示不带路径的文件名)。

echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

DOS 环境再次略过,而且我觉得这里用 bash 的参数 ${i%.TXT}.zip 替换更帅。

下面的一些 SED 说明略过,需要的朋友自行查看原文。

{ Source. Thanks bones7456. }

2009年12月6日日曜日

Ubuntu Tips(随时更新)

1 在ubuntu中firefox的flash乱码问题的解决
  • 打开文件/etc/fonts/conf.d/49-sansserif.conf
  • 将除monospace以外(3处)的字体修改为wqy-zenhei
  • 需要管理员权限
2 Ubuntu9.10中QQ自动退出问题的解决
  • 打开文件/usr/bin/qq
  • 增加一行 export GDK_NATIVE_WINDOWS=true
  • 需要管理员权限
3 audacious2中MP3文件的TAG中的中文乱码问题解决
  • 使用easyTag软件将MP3的TAG中的文字编码变换为UTF8
4 用evince看PDF文件时的乱码问题解决
  • sudo apt-get install poppler-data


2009年9月5日土曜日

Linux 死机了怎么办

Linux 会死机么?我可以很肯定地说,会!要让 Linux 死机很容易,但难的是在死机以后如何安全的让他摆脱死机状态,本文讲述如何从 Linux 的死机状态中挣脱出来。

Linux 死机有很多种情况,最常见的是系统负载过高导致的。如上次介绍的 fork 炸弹就是这个原理,此外还可以运行内存耗用极大的程序(如虚拟机),也会迅速提升系统负载。由于系统负载过高导致的卡死,一定是解决的越快越好!此时必须记住的是,不能再试图依赖任何图形界面的东西,如 Gnome 的系统监视器(这是我从 Windows 遗留下来的愚昧习惯……),这只会继续加重这种卡死的局面。那怎么办?

不要怕,Linux 最初就是不需要图形界面的,因为有一个很强大的文字界面。按 Ctrl-Alt-F1(F1-F6 一般来说都可以),然后等一会儿,就会切换到 tty,也就是所谓的文字界面。这个时候需要用用户名密码登入。注意,可能键盘输入的速度比较慢,不过应该还是可以忍受的。下面在提示符后面输入 top 回车,这时会看到一张动态的表,上面列出了耗用资源最多的进程。观察它刷新一两次,按q退出,然后输入 kill ,其中的 PID 你可以在 top 里面看到。这个时候应该会快了不少,如果你发现没有成功结束掉,就再输入 kill -KILL ,这次基本上就没问题了。

除了上面这种情况外,一些底层软件的 bug 也可能导致一些奇怪的死机问题。我某位同学近日就因为莫名其妙的死机强制重启把 ext4 的分区给伤了。(最后是 sysreccd 修复了,貌似是分区表部分损坏)据其说,死机是键鼠均无反应。一般来说,系统负载高导致的死机,在可怕键盘也会有反应,有人说如果死机到键盘无响应“负载都无限大了”,亦有人说这可能是 X Server 与驱动配合有问题导致的。不过我们考虑一下遇到这种情况怎么办?

OK,这是今天才学到的方法,叫做 reisub,这个方法可以在各种情况下安全地重启计算机。大家在键盘上找,可以找到一个叫做“Sys Rq”的键,在台机的键盘上通常与 Prt Sc 共键,在笔记本可能在其他位置,如 Delete。以台机为例,要使用这种方法需要按住 Alt-Print(Sys Rq),然后依次按下 reisub 这几个键,按完 b 系统就会重启。

下面解释一下这个方法:其实 Sys Rq 是一种叫做系统请求的东西,按住 Alt-Print 的时候就相当于按住了 Sys Rq 键,这个时候输入的一切都会直接由 Linux 内核来处理,它可以进行许多低级操作。这个时候 reisub 中的每一个字母都是一个独立操作,他们分别表示:

unRaw 将键盘控制从 X Server 那里抢回来
tErminate 给所有进程发送 SIGTERM 信号,让他们自己解决善后
kIll 给所有进程发送 SIGKILL 信号,强制他们马上关闭
Sync 将所有数据同步至磁盘
Unmount 将所有分区挂载为只读模式
reBoot 重启

这6个字母的顺序是不可以记错的。那怎么记呢?这里提供一个个人认为比较好的方法:单词 busier(busy 的比较级,更忙)倒过来就是了。

基本上就这样了,Linux 的死机本来就不多见,现在见了也可以安全解决,多好~

2009年7月20日月曜日

Ubuntu中删除旧内核的方法

sudo aptitude purge ~ilinux-image-.*\(\!`uname -r`\)

2009年1月31日土曜日

硬盘安装Ubuntu 8.10无法分区最简单的解决方法

关于Ubuntu 8.10硬盘安装无法分区的情况,最开始的解决方式为用U盘或者双硬盘帮助分区,使用的时候比较繁琐,必须要先制作引导U盘,今天在Ubuntu中文论坛发现已经有人提出更好的解决方式,不需要使用U盘或者双硬盘,顺利的在安装过程中对硬盘进行分区,不过使用的是alternate镜像。

详细步骤如下:

第一、硬盘安装进行到分区步骤,对话框中出现空白时,按下ALT+F2进入shell(busybox内建的shell),回一下车到命令提示符。

第二、在shell中ls一下,会发现一个名为hd-media的目录,进去检查一下,应该看到这个目录就是存放iso映像的那个硬盘分区的挂载点。

第三、检查完了之后,从hd-media回到根目录下,用umount - l hd-media来卸载它。“- l”参数一定要加,否则卸载不掉。

第四、卸载之后,按ALT+F1回到安装界面,这时还停在分区步骤,通过对话框下面的“返回”按钮来到“安装程序主菜单”,再次选择“硬盘分区”,此时分区步骤应该就正常了,能够看到它扫描出来的硬盘分区。

第五、对硬盘进行分区,完成安装!

2008年8月31日日曜日

gnome 自启动程序设置

呼...花了几个小时,终于弄明白了,没想到这个东西挺隐蔽而且网上基本搜不到...

以前我一直用~/.gnomerc,不过这个是在gdm刚加载时调用的,如果这个时候运行一个窗口程序,一开始会没有标题栏等等,挺不爽.

后来知道了可以用gnome-session-properties(System->Preferences->Sessions)来进行配置, 里面有个startup.

但是我想知道其具体配置文件在哪里,网上很多说在~/.gnome2/session,我看了,一开始没有这个文件,但是在gnome-session-properties里选择Save the current session后就有这个文件了.

如果这个文件不存在,gdm会找/usr/share/gnome/default.session

不过我觉得这个并不是我想要的,虽然也能起到自启动的效果. 因为它里面的内容和gnome-session-properties的startup配置并不符合.

最后花了九牛二虎之力找到了,在~/.config/autostart目录下,里面有若干.desktop文件. 虽然对其格式还不是非常了解,但是肯定这就是我要找的了.

呼...

自己动手提高ubuntu系统的性能

在每一个基本的系统中,都包含有各种各样的基本进程,用于检查系统服务,和操作系统通信等等。进程和系统的性能表现有着很大的关系,因此,一个系统管理者应该清楚了解当前系统中正在运行什么东西,有什么资源可用等等,只有这样,你才能够调整配置,例如,禁止不需要的进程,打开必须的监护程序以及将你的内核调整到最优化,最后得到一个最适合自己使用的最好的系统。Ubuntu是一个为大众设计的系统,这也就决定了其系统设置的大众化,换句话说,臃肿化。为了适应兼容性而支持的很多东西,我们其实不一定需要。在这里,笔者试图讲解一些通过调整内核参数,shell参数以及特定应用的设置来优化系统的方法,供大家参考。需要注意的是,不同的ubuntu系统有着不同的启动脚本,并有着不同的运行进程,这里我只能以7.04系统为基础来讲解。其实自己学会对进程进行追踪查看是非常重要的,只有这样你才能在不同的系统中都游刃有余。另外,如果要更加深入调整系统,那么自己编译一个属于自己的系统是最合适的,本文没有牵涉这么深入的东西。如果你对自己编译 linux系统感兴趣,可以参考这篇文章和这篇文章。

本文假设你有一点点基本使用linux的基础,所以很多东西只是讲一个概念性的大纲,想深入了解的话,网络上有很多文章。如果你是系统高手,基本就可以不用看本文了,你会觉得很简单,如果你是连ps,who -r都不知道的新手,建议你还是先放google搜索一些入门文章,并亲自使用linux一周以上,再回过头来看这篇文章。本文很大程度上参考了 Ubuntu Performance Guides,篇幅较长,故分两页发出。

刚才就几次提到进程,那么,我们应该怎么理解这个词语?广泛得说,所有在系统中运行的,用于执行各种各样任务的,都是一个进程,只不过根据具体执行任务的不同可以有所区分,例如,用于管理和维持操作系统运行的属于系统进程,而用于处理用户需求的就是用户进程。

进程并不是一个独立的概念,它是相互交互的,很多进程都为其他进程提供服务,或者携手共同完成某一个功能。这些服务中,有一些对于系统的运作是非常关键的,例如X-Windows服务。绝大多数的系统进程都是服务性质的进程,而绝大多数用户进程则是应用程序类进程。应用程序,比如你现在在使用的 FireFox(或者其它,估计FF最多吧)通常是由一个或多个满足用户需求的进程组成。总的来说,服务的开启和关闭是基于系统需求的,而应用程序的开启和关闭,则是基于用户的需求的。

我们上面说的这些进程阿,服务阿啥的,其实之间的区分并不是很明显,举个例子,Gnome的桌面系统就是由各种程序和进程组成,而他们不仅提供其它程序需要的服务,还可以支持用户的需求。GDE完全可以被称为是程序,进程,应用和服务的集合体,这不会产生任何冲突。

当然,我们还是要稍微做一下区分,后面才方便继续讲解。现在就统一一下,进程表示任何可以产生运行中的进程标志符的东西,程序则表示能产生进程的可执行文件。用户能够直接使用应用程序,而操作系统才使用服务。
进程基本操作

在你的机器上,唯一能够消耗你资源的就是正在运行的进程。如果当你发现自己的系统突然很慢,运行不正常时,通常只有两个可能,一种是某些进程运行异常,另一种就是某些进程所消耗的资源已经大于你所拥有的资源。

当然,想看看什么东西正在你机器上运行其实很简单,使用ps -aux或者top命令即可,这些东西资料很多,我就不多说了,实在不行man top或者man ps吧。当然,对于初学者来说最方便的还是利用图形化界面的系统监视器,如图:

screeshot(点击缩放)

所有信息都尽显眼前。注意,在系统监视器中,你不仅能看到进程运行情况,还能看到磁盘使用,CPU使用等很多有价值的信息,这些信息是接下来的部分可能用到的。

ok,现在我们知道,如果系统异常,如何去确定是什么进程异常了。但是接下来该怎么处理呢?无论是命令行还是图形界面显示,你都可以看到每一个进程都有属于自己的ID,也就是PID。它们都是进程的句柄,而不是表示真实的进程。这有什么区别?对于一个拥有多线程的进程来讲,可以让所有的线程都拥有同一个句柄,也可以让每一个线程都拥有一个句柄。太专业了?恩,通俗来讲,这就相当于……进程的身份证,我们通过它来标志进程。这个东西在ubuntu中默认可以有 32768个不同的PID,每有一个新的进程,就分配一个当前未用的PID给它。

好了,让我们找到那个让我们系统变慢的该死的罪魁祸首,看看它的PID,然后用kill PID命令来关闭它。等等,你确定就是这个进程影响了你的系统?你确信没有错杀好人?好吧,其实可以先用kill -stop PID命令来暂停一个进程,看看没有了它,我们的系统是否正常。如果发现了冤假错案,没关系,kill -cont PID能让进程继续工作。

除了直接使用kill PID之外,我们还有更进一步的kill进程的办法。kill PID仅仅是发出一个TERM信号,然后进程能捕捉这个信号,开始释放资源,关闭程序,这不是一下子就完成的,因此在关闭程序之前,你可以结束打开的文件和完成正在做的任务。但是这导致一个问题,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号,而且如果进程失去响应了怎么办?别急,我们还可以试一试kill -1 PID命令,这个命令发送的是hang up信号,含义是“中止信号”,它告诉进程,终端已经被kill了。但这个信号同样只被运行良好的进程所拦截。假设这两种方式都无法结束进程,那么只能使用kill -9 PID了。这个命令发送的是真正的kill信号,对于这个信号,进程是不能忽略的。这是一个“我不管您在做什么,立刻停止”的信号,也就是说进程立刻被终止,不实施清理操作。

信号是用来与守护程序和进程通信的。任何活动任务都是一个进程,而守护程序是等待对某些事件做出反应或者按照日程安排执行任务的后台服务。一个程序必须有建在其中的信号处理程序用于捕获和应答信号。在LINUX中的signal参考指南解释了各种不同信号和这些信号的用途。常用的信号除了上面介绍的以外,还有INT,CHLD等。
进程操作进阶

当然,仅仅了解上面的知识,对于对进程的理解,还是不够的。下面,我会介绍更多的关于进程的知识。

首先,我们需要知道,并不是所有的进程都会被动态分配PID,至少有两个进程不会,就是kernel和init。kernel进程的PID是0, 一直是0,而且你无法从ps,top这些命令中看见它,当然,也无法用kill命令来终止它。init进程是主父进程,什么意思呢?每一个进程都需要一个父进程来监管它,父进程的作用就是接受子进程的返回值和状态值。而如果任何一个进程的父进程被终止,init就会成为它的父进程。init进程的PID固定是1,从理论上讲,你也可以终止它,但是千万不要试图这样做,因为它是用来清除呆死进程的,一旦将其kill,系统最终将崩溃。

除了他俩,还有一些进程是你不应该kill的,包括Zombies,/O Bound—A和Interception。事实上,我们很少解除这几个进程,普通用户也没必要接触它们,因此,在这里我不会详细解释它们的用途,有兴趣的朋友可以自己google。

其它进程,在保证系统本身不崩溃的情况下,一旦有异常你都可以试图去kill,不过要知道,kill命令只作用一次,也就是说,假如,我是说假如,这个进程在被kill后又重新自启动,那么你不得不再运行一次kill,这样循环。当然,此时,你就不能一直陪它kill下去了,追踪查看其自启动的根源才是正确的做法。你觉得这太麻烦了?好吧,还有一个懒办法,就是看看这个进程的名字,然后用kill name来阻止它。我知道很多地方都有介绍kill -9 -1这个命令,但是你需要知道,这个命令会kill你所有的进程,包括界面进程以及终端。而且如果你是root权限……它会连所有系统应用都一起 kill,然后,你的系统就将崩溃。所以用这个命令,你还不如直接按下你的重新启动按键,还更加省心……
进程的启动

我们能够查看正在运行的进程,查看进程的具体信息,但是,我们能不能知道它们是怎样开始的?难道是和孙猴子一样从石头里面崩出来的?你也许会看它的 PPID,恭喜你,摸着点门道了,but……你会发现大多数进程的PPID都是1,init进程。而事实上,进程的启动原因可能是很多种,启动脚本,设备配置脚本,网络变化,甚至是任务日程等等等等。因此,我们需要探查进程启动的秘密。
启动脚本

看看你的/etc/init.d/文件夹,你会发现其中包含了很多用于启动和停止系统服务的脚本,而它们,都将以链接形式存在于/etc/rc0.d, /etc/rc1.d以及类似目录中。例如,在/etc/rc1.d执行命令ls -l,你会看见如下结果:

lrwxrwxrwx 1 root root 13 2007-04-21 22:01 K01gdm -> ../init.d/gdm*
lrwxrwxrwx 1 root root 17 2007-04-21 21:59 K01usplash -> ../init.d/usplash*
lrwxrwxrwx 1 root root 17 2007-04-23 14:54 K09apache2 -> ../init.d/apache2*
lrwxrwxrwx 1 root root 17 2007-04-21 21:58 K11anacron -> ../init.d/anacron*
lrwxrwxrwx 1 root root 13 2007-04-21 21:58 K11atd -> ../init.d/atd*
lrwxrwxrwx 1 root root 14 2007-04-21 21:58 K11cron -> ../init.d/cron*
lrwxrwxrwx 1 root root 16 2007-04-21 21:59 K19cupsys -> ../init.d/cupsys*
lrwxrwxrwx 1 root root 15 2007-04-21 21:59 K19hplip -> ../init.d/hplip*
lrwxrwxrwx 1 root root 22 2007-04-21 21:58 K20acpi-support -> ../init.d/acpi-su
……………………………..

如果你的运行级别是1,init就会进入/etc/rc1.d并调用其中的链接符号,也就是启动相应的进程,以此类推。如果想知道目前系统的运行级别,最简单的办法就是用who -r命令,会显示:

run-level 2 2007-05-04 10:09

这就表示我目前的系统运行级别是2。在boot的时候,所有/etc/rc2.d目录下对应的init脚本的输出都会存到/var/log/messages这个文件中,你可以根据它来判断哪些进程被执行了。
启动设备

udev进程用于动态管理设备的配置,这个进程监视和管理即插即用设备。一旦这些设备生效,存在于/etc/udev/rules.d/文件夹下的哪些脚本就会生效,调用不同的应用程序。
shell启动脚本

每当你登入登出系统,或者是启动了一个新的shell之后,都会执行配置脚本,每一个脚本都会启动进程。对于笔者使用的ubuntu而言,默认的shell是bash,相应的配置脚本如下:

/etc/profile:每次登录shel都会执行,全局配置文件
$HOME/.bash_profile:基于用户自定义,每一个用户都可以有自己的登录脚本
/etc/bash.bashrc:交互式非登录全局配置脚本,这个文件在.bashrc中会调用
$HOME/.bashrc:交互式非登录用户自定义的配置脚本,也是我们大多数时候需要修改的文件
/etc/bash.logout:不一定存在,如果存在的话,每次用户登出时调用它
$HOME/.bash_logout:同上,只不过是用户自定义的

我们可以注意到,上面这些脚本大致可以分为两类,一类是用于登入登出的,一类是交互式。它们有什么区别么?简单得说,每当你登入你的系统时,登入脚本和交互式脚本都会执行。而当你打开一个终端窗口时,只有交互式脚本才会被执行。
桌面脚本

linux喊了一万年的要易用,要占领桌面系统,简单说来,就是希望有一个漂亮易用的图形界面。大多数人的大多数应用还是基于图形界面的,因此,除了上面介绍的shell脚本,我们还应该关注一下图形界面脚本。

在启动图形界面的时候,首先会运行/etc/X11/xinit/xinitrc, /etc/X11/Xsession和/etc/X11/xinit/xserverrc这三个脚本。它们会设置相应的环境变量,并在最开始启动时运行应用程序。在X-Windows启动完毕之后,就是Gnome的启动,它会调用很多程序,产生很多进程,也就是类似于Windwos下的开机自启动程序。到底是哪些进程呢?我们可以从存放系统级别启动脚本的/etc/X11/gdm/目录,用于用户自定义启动程序的$HOME/.gnomerc文件,或者通过系统>首选项>会话菜单来查看:

screeshot(点击缩放)

好,问题来了。既然有这么多的地方都能进行开机自启动程序的添加,难道它们都是完全一样的么?这样有什么意义呢?

恩,它们当然不是完全一样的,而是各司其职。

如果你希望自启动程序是作用于使用X-Windwos的所有人,那么你要修改的地方就是/etc/X11/Xsession,或者把脚本放置到 /etc/X11/Xsession.d/目录下。如果仅仅是希望对你自己使用X-Windwos时生效,则修改$HOME/.xsession即可。

如果你希望自启动程序是作用于使用Gnome的所有人,那么你要修改的地方就是 /etc/X11/gdm/PostSession/Default,它会仅仅对Gnome使用者起作用,而不是KDE使用者或者其他。或者把脚本放置到 /etc/X11/Xsession.d/目录下。如果仅仅是希望对你自己使用Gnome时生效,则修改$HOME/.gnomerc即可。

小知识:Gnome和X-Windows的区别?
X- Windows是图形界面底层,提供的功能是在屏幕上构造方块(窗口),然后画出里面的元素,但不提供交互式操作。gnome,kde这些都是基于X -Windows的不同风格的界面,属于桌面环境。怎么理解这个桌面环境呢?基本的意思是指“ Mac OS 和 Windows的图形界面有,而X没有却应该有的东西”。通常是一组有着共同外观和操作感的应用程序,和程序库,以及创建新的应用程序的方法。事实上你可以同时有两个文件管理器,两个面板,等等,并不冲突,因为它们都是属于应用。

桌面应用

插入光盘,就会自动弹出文件浏览器,插入数码相机,就会自动弹出照片导入程序,等等。这些应用是怎么实现的?如何禁止程序的自动执行?如何自定义在即插即用设备被认出以后的启动程序?
答案就在 系统>首选项>可移动驱动器和介质里。打开它,你就明白怎么回事了,这东西实在太简单,我就不多说了。只有一点补充的,就是如果你要使用一款新的即插即用设备,而这种设备在可移动驱动器和介质选项中没有,那么此时你就必须求助于udev了。至于udev的具体知识,讲起来又是一篇文章,所以就不讲了,还是那句话,放 google~~^_^。
评估资源

刚才我们一直再说资源资源,当然,系统资源的使用情况直接决定了你系统当前的性能。那么,我们如何才能对自己系统的性能做一个基础评估呢?在评估之前,我们需要对资源做一个更加详细的解释。所谓的资源,都是指进程所能使用的资源,包括了CPU 处理能力,磁盘空间,磁盘I/O,RAM使用情况,显存使用情况,网络流量等。而这些资源的当前使用状态,我们都是有办法自己获取的。
系统监视器和proc

正如大多数linuxer所知道的那样,/proc挂载了一个虚拟文件系统,专门用于列出当前系统资源情况和正在运行的进程。在这里,所有的东西都是动态的,随时可能改变的。最关键的是,/proc目录下有很多以数字命名的文件夹,这些文件夹都对应了某一个响应PID的进程,内含进程的很多信息,包括使用命令,运行环境等。还有一些不是以数字命名的文件夹,那是设备驱动和内核的情况,例如,cpuinfo这个文件就提供了系统中cpu的相关信息。

当然,你可能觉得从这里面获取系统资源信息实在太麻烦了,你会抱怨,拜托,我仅仅是初学者,有没有直观的办法?sure!刚才我们说的CPU处理能力,磁盘可使用空间,内存情况,网络情况,你统统都可以从系统监视器中看到。监视器以曲线图的形式把情况呈现在你的面前,你可以根据它评估系统的运行是否良好,有没有异常的发生。

screeshot-1(点击缩放)
其它

那么,监视器就是万能的?no,至少显存和磁盘 I/O的情况它就无法呈现给你。在实际使用中,可能会发生你的系统中有好几个磁盘,但某个磁盘的 I/O通道堵塞会导致系统性能下降的现象。有什么办法来确定是哪个通道在搞鬼呢?这里,iostat就可以帮助我们了。这是一个小的,评估I/O性能的软件,通过sudo apt-get install sysstat来获得它。安装完后直接输入iostat命令,就会显示:

avg-cpu: %user %nice %system %iowait %steal %idle
7.18 0.08 3.58 2.34 0.00 86.83

Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 16.63 0.19 0.16 1046 877
sdb 0.01 0.00 0.00 0 0

包括基本CPU负荷以及I/O情况。我机器上磁盘数量较少,所以结果比较少。好了,光知道这些数据是没用的,我们需要做的是根据这些数据来分析系统负荷。我们假设现在sdb设备数据量不正常,好,接下来就用mount命令来看看,是哪个文件挂载到sda下的,得出文件路径名后,用lsof来查看这个目录下打开了哪些文件,哪些进程,以及相关信息。这样,就能有的放矢得来寻找到让你磁盘I/O情况异常的东西。

之后谈谈显存的情况读取。首先谈谈我们为什么要关注显存,显存的容量会直接影响你的显示情况,例如,如果你只有一块老的,256K显存的显卡,那么屏幕的显示最高也就是支持到 800×600,16位色深。如今,大部分的高端显卡都拥有至少128MB的显存,能够轻松在32位色深的情况下上到1280×1024的分辨率。更多的显存同样对游戏以及桌面的逼真度有益,因为可以由显存的一部分来保持主画面的显示,其它空余下来的显存就可以用来体现各种层面的仿真元素。我们可以通过 lspci –v 命令来显示所有PCI卡,包括显卡的存储关联情况。这个命令有什么用呢?当你遇到硬件问题,比如缺乏关键的硬件环境支持时,可以用这个命令来诊断到底是什么设备出了问题。这个命令在我这里奏效,但我不保证在所有的机器上都能奏效。在显示的情况中找VGA这一栏,可以看到显示信息如下:

01:00.0 VGA compatible controller: ATI Technologies Inc RV370 [Sapphire X550 Silent] (prog-if 00 [VGA])
Flags: bus master, fast devsel, latency 0, IRQ 16
Memory at 20000000 (32-bit, prefetchable) [size=256M]
I/O ports at 2000 [size=256]
Memory at 30110000 (32-bit, non-prefetchable) [size=64K]
Expansion ROM at 30120000 [disabled] [size=128K]
Capabilities:

从这里,我们就可以看出我的显卡是256M显存。
实战演练

在经过上面基础知识的介绍,就算是超级新手,也大概应该明白一些东西了。好,下面我们就进入实际调整的环节。同样,所有内容都是基于我的ubuntu feisty系统,如果你的不是这个系统,请仔细核对后再实践,我不对任何内容做“肯定可行”的保证。
加快系统启动速度

刚才我们已经介绍过了,每次开机启动的时候,启动脚本都放在/etc/rc*.d/目录下,这个*取决于你的运行级别。但是,并不是所有的脚本都是你目前这个系统需要的。如果把那些你不需要的启动进程都去除,那么不仅仅是系统启动速度会变快,开机后分配给你使用的资源也会增多。

所以现在,我会告诉你一些常见的可禁止的启动进程。在此之前,我得提醒各位,对于那些我没有提及的进程,除非你很清楚知道自己在干什么,否则最好不要去动它们,比如gdm(Gnome桌面)或者module-init-tools(内核模块)这种,要是误操作了,系统错误可别怪我……

事实上,我们可以通过系统–》管理–》服务的图形界面来做这种活,但是在这里,它并没有列出所有的服务,因此,为了对所有的启动进程都能进行自定义,我们选择sysv-rc-conf工具来进行操作。可以通过

sudo apt-get install sysv-rc-conf

命令来安装它。然后以root权限打开,界面如下:

sysv-rc-conf(点击缩放)

第一行的一排数字表示你的系统运行级别,对应的列就是该级别对应的启动进程,具体打开和关闭启动进程的操作方式很简单,下面就有说明。

好了,介绍一下常见的可以考虑去除的进程吧

* anacron — 这是一个一个自动化运行任务守护进程。你可以把它屏蔽,然后用cron来安排计划任务。

* atd and cron — 如果你根本就不会使用计划任务功能,那么可以连这个也不要。不过它占用的资源极少,不是特殊情况也没有必要禁止它。

* apmd — 这是一个电源管理方面的服务,专门用于监视那些不支持ACPI的旧系统的电池。如果你使用的笔记本比较新,或者使用的是台式机,就没有必要要它。

* acpid — 这个服务用于监视电池电量,以及那些键盘上的特殊功能键,比如屏幕亮度调整键,音量控制键,无线网卡开关等等,也可以监视台式机键盘上一些网络应用等类似快捷键。如果你使用的不是笔记本,也不需要这些快捷键,就可以禁止它。

* bluez-utiles — 提供蓝牙服务的支持,怎么操作就取决于你有没有蓝牙设备了。

* dns-clean, ppp, 和pppd-dns — 这些服务用于动态拨号连接。如果你使用的不是拨号,就可以禁止。

* hplip — 提供对HP Linux 图像和打印系统的支持。建议禁止,因为就算没有它,也可以通过lpr这些来实现打印。

* fetchmail - 接受邮件的守护程序,建议关闭。

* nvidia-kernel- ATI显卡用户可以关闭,自己编译显卡驱动的用户也可以关闭。

* hwtools - 优化irqs的工具,不用irqs的话就可以关闭

* mdadm, mdadm-raid, and lvm — 用于支持RAID的文件系统和逻辑卷管理(lvm)。如果没有使用它们,就可以禁止。不过笔者建议在熟悉基本操作后可以自己尝试学习一些LVM相关的知识,还是挺有意义的。关不关看自己吧。

* nfs-common, nfs-kernel-server, and portmap — NFS(Network File System)是一种分布式文件系统,允许网络中的安装不同操作系统的计算机间共享文件和外设。如果你不是经常需要NFS服务,就可以先禁止它,等要使用时,再用下面的命令来启动它们:

sudo /etc/init.d/portmap start
sudo /etc/init.d/nfs-common start
sudo /etc/init.d/nfs-kernel-server start

* pcmcia and pcmciautils — 提供对笔记本上PCMCIA设备的支持。如果没有PCMCIA插槽,还要它干吗?

* powernowd and powernowd.early — 用于控制可变速CPU的服务。现在新的计算机CPU大部分都是可自动变速来节省电量了,所以只有那些很老机器的用户才建议关闭它。事实上,这部分用户已经很少很少,所以我个人建议还是保持开启。

* readahead and readahead - 一般只有内存非常小的用户,才建议关闭这个启动进程,因为它会预加载一些库,让一些程序在启动时更快,这样会消耗一些内存。如果你内存比较大,就没有必要管它。

* rsync— 用于在计算机之间同步文件的服务,极少人用到,基本都可以禁止。

* vbesave — rvices monitors the 监视Video BIOS实时配置的服务。它是ACPI的功能之一,通常是笔记本需要在屏幕显示或者外接显示(投影仪之类)之间切换时才起作用。如果你的计算机不支持 ACPI或者没有这种应用的需求,就可以禁止。

调整内核参数
查看参数

不要把内核参数想象得太神秘,事实上,有很多参数是你自己就可以调整的。用下面这个命令在终端中执行试试看,结果是什么?

sudo sysctl -a | sort | more

是的,显示的就是一系列内核参数。即使你不用sudo,也可以看见大多数参数设置。这些显示的参数都很好理解,比如kernel.threads- max = 16379,就表示同时运行的最大进程数是16379个。也许你会奇怪,PID的最大值不是65536么?怎么这个设置小这么多?是的,这就是我在这里介绍调整内核参数的原因。我们完全可以通过调整这个值来适应不同的系统,比如如果你的cpu频率很低,内存很小,就可以把这个值缩小一些。如果你的cpu很棒,内存很足,就可以不用管它,甚至调大也行。这完全取决于你的机器配置,和你自己的想法。事实上,在你安装ubuntu的时候,它就会自动根据可用资源来调整这个参数,所以不同机器上,这个参数可能是不同的。但是记住,机器调整的毕竟没有人调整的好,无法最大限度发挥系统的性能。
调整参数

好,我们现在已经可以看到很多内核参数了,那么,接下来的事情就是根据自己机器的情况来调整。通常有两种方法来调整参数,一种是在命令行下,通过类似命令

sudo sysctl -w kernel.threads-max=16000

这样来调整。这种方法调整过的参数会立刻生效,但是不会永久生效。什么意思呢?也就是说一旦你重新启动,所有改动就会消失。那这样岂不是毫无意义么?所以还有第二种方法,就是直接修改/etc/sysctl.conf文件。这个文件本身没有任何内容,有的东西全部是注释,就等着你来修改。比如,你可以将

kernel.threads-max=16000

这行命令加进去,这样,在重新启动之后,threads-max的值就会变成16000了。

通常,我们应该配合这两种办法来进行内核参数调整。首先用命令行形式调整,看看并测试直观的效果,如果比较满意,再把调整写入文件中。命令行调整的好处就是,不管你怎么胡乱修改,甚至导致系统错误,没关系,只要重新启动,一切就将恢复原样。
修改共享内存

在linux下,不同的应用程序可以共享同一块虚拟内存地址,这样方便不同程序之间的通信和信息共享,通常有两种共享内存的分配方式:临时和永久。临时分配的意思就是在所有共享的应用程序都释放内存句柄,不再需要它时,内存就会被收回。而永久分配的意思就是即使没有任何应用程序使用它,这些共享内存也会继续保持,这就有利于将状态保存于其中。

我们可以通过ipcs命令来查看进程间通信的状态。输入ipcs -m来浏览内存使用情况,显示结果为

—— Shared Memory Segments ——–
key shmid owner perms bytes nattch status
0×00000000 131073 windstorm 600 393216 2 dest
0×00000000 393218 windstorm 600 393216 2 dest
0×00000000 425987 windstorm 600 393216 2 dest
0×00000000 229380 windstorm 600 393216 2 dest
0×00000000 262149 windstorm 600 393216 2 dest
0×00000000 294918 windstorm 600 393216 2 dest
0×00000000 327687 windstorm 600 393216 2 dest
0×00000000 360456 windstorm 600 393216 2 dest
0×00000000 458761 windstorm 600 393216 2 dest
0×00000000 3964938 windstorm 600 393216 2 dest
0×00000000 524299 windstorm 600 393216 2 dest
……..

是不是有点晕了?我们可以看到一些共享内存的信息,包括共享内存ID,所有者,状态等等,但是这对于普通用户来说是不够的。你总得让我知道是谁在用吧?所以,我们应该使用下面这个命令

ipcs -m -p

来看看输出结果:

—— Shared Memory Creator/Last-op ——–
shmid owner cpid lpid
131073 windstorm 5473 4790
393218 windstorm 5568 4790
425987 windstorm 5566 4790
229380 windstorm 5413 5513
262149 windstorm 5490 8277
294918 windstorm 5512 4790
327687 windstorm 5496 7300
360456 windstorm 5496 7300
……..

好了,现在我们知道这些共享内存块分别是谁创建的(cpid),谁最近一次访问(lpid)。有时候,你会发现一些被遗弃的共享内存,就可以用ipcrm -m|-q|-s shm_id来删除共享内存信息。

但是通常情况下,如果所用的系统是作为数据库或者高性能网络服务器使用,我们更加关心的是如何分配更多的共享内存,而不是清除废弃的共享内存。那么首先,我们可以通过sysctl kernel | grep shm命令看看当前共享内存的分配情况。

sysctl kernel | grep shm

我的机器上果如下:

kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 33554432

这是什么意思呢?这些数据表示,当前总共有33,554,432 bytes (32 MB)可用共享内存,每一个单独的程序最高能够分配到2,097,152 bytes,也就是2 MB,而最小的分配单元是4096 bytes。这些数据对于常用的应用来说完全足够了,但是如果是那种类似于数据库的高性能应用,可能你就需要考虑增大它们的数值了。修改方法?请参考“调整参数”小节。

ipcs还有很多其他的查看方式,比如ipcs -m –t能够显示最近一次共享内存的访问的时间,ipcs -m –c则可以显示访问权限,请man ipcs来自行查阅更多用法。
修改个人用户设置

在内核设置层面之上,还有很多个人用户配置的参数,ulimit命令就是bash下提供的,查看对指定应用的限制值的工具。你可以通过ulimit –a命令显示当前设置:

core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) unlimited
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

上面的信息什么意思?举个例子,

open files (-n) 1024

表示一个用户shell最多可以打开1024个文件,想增加怎么办?ulimit -n num即可。

core file size (blocks, -c) 0

表示core dumps功能关闭。想打开怎么办?ulimit -c num即可。
如果你只是普通身份用户,则只能对数值进行减少的修改。如果想增加数值,需要用root权限修改。而且,一些参数的上限是和内核参数对应的,比如你可以增加打开文件句柄的数目,但数目的最大值不能超过内核参数fs.file-max设置的值(sysctl fs.file-max看看)。
修改日志数据

好吧,我知道这招有些冒险,但是确实很有作用。为了避免一些朋友在使用后出问题又无法解决,我在后面也附上了问题解决方法。

我们知道,无论是Ext3还是ReiserFS,都有三种日志方式:
1) Journal Data Writeback
2) Journal Data Ordered
3) Journal Data

三者的不同点,简单得说就是实际数据被写入文件系统以及相关日志的时间不同。默认系统采用的是Journal Data Ordered方式。如果采用Journal Data Writeback方式,能够有效提高系统速度,只不过这是有代价的:一旦系统崩溃,在通过日志恢复后,你可能只能得到一些旧的数据,而不是最新数据。所以,在修改前,请三思,如果你是对当前工作进度的备份要求非常苛刻的人,最好不要使用这个办法。

那么,接下来就介绍一些具体的修改办法,首先, 如果你是Ext3系统,需要进行以下步骤,否则可能在重新启动时出错:

sudo tune2fs -o journal_data_writeback /dev/hda1

这是人工在重启之前把文件系统设置为writeback模式。用下面这个命令来确认是否得到了执行:

sudo tune2fs -l /dev/hda1

千万注意,ReiserFS文件系统不用这样。

然后sudo vim /etc/fstab,在你的root分区mount属性中增加

data=writeback

这一句,使其看起来是这样的:

/dev/hda1 / ext3 defaults,errors=remount-ro,atime,auto,rw,dev,exec,suid,nouser,data=writeback 0 1

保存,然后sudo vim /boot/grub/menu.lst,在下面两行加上粗体属性:

# defoptions=quiet splash rootflags=data=writeback
# altoptions=(recovery mode) single rootflags=data=writeback

这样的话,即使升级内核,增加的标志也会保持,不会被覆盖。最后运行sudo update-grub即可。

ok,再提醒一句,这样做是比较冒险的。我知道你很有冒险心理,所以一旦重新启动出问题时,请用一下方法解决:
将系统重新启动到恢复模式下,在命令行下输入

mount -o remount,rw /dev/sdXX/

这个sdXX就是你的硬盘分区,这样就允许你修改硬盘上的fstab和menu.lst文件,将改变还原,然后在正确的系统中再去思考到底哪里出了问题。
杂项

1. 上面已经介绍,/etc/init.d/下面的都是启动脚本,默认这些脚本是按顺序启动的,实际上,如果你使用的是SATA 或SCSI,可以并行启动这些脚本程序,加速启动过程。而如果你的机器配置较老,则最好还是不要修改。修改方法是通过命令

sudo vim /etc/init.d/rc

找到并修改该行:
CONCURRENCY=none
为:
CONCURRENCY=shell

2. 长期使用 Ubuntu 后有一种感觉,那就是在 GNOME 中启动应用程序时,速度越来越慢。在 Ubuntu 英文论坛那边看到一个技巧,可以对这个问题起到改善作用。打开 /etc/hosts 文件,可以看到类似下面的内容:

127.0.0.1 localhost
127.0.1.1 windstorm

现在,只需在第一行的末尾加上主机名即可

127.0.0.1 localhost windstorm
127.0.1.1 windstorm

保存后,重启系统,更改生效。

3. Pango是一个着重于国际化的,用于输出和文本渲染的库,但是这个库可能导致firefox等一些程序有着过高的cpu占用资源。我们可以

sudo vim /etc/environment

然后在其中添加:
MOZ_DISABLE_PANGO=”1″

这样就可以禁用Pango了。

2008年8月30日土曜日

Ubuntu Linux系统的启动过程

BIOS 自检

启动 GRUB/LILO

运行 Linux 的系统内核

读取系统引导配置文件 /etc/inittab 中的信息运行系统的第一个进程 init

执行系统初始化脚本 /etc/init.d/rcS

根据运行级别(X)配置服务执行 /etc/init.d/rcX.d/[KS]*

终止以“K”开头的服务

启动以“S”开头的服务

运行 getty 等待用户登录

执行系统初始化脚本 /etc/init.d/rcS 时会执行 /etc/init.d/networking 启动网络配置

在执行 /etc/init.d/rcX.d/ 时,若运行级别为 2~5

若安装了Gnome/KDE,还会运行 gdm/kdm

运行脚本 /etc/rc.local 执行本地的其他启动配置

INIT 及其配置文件

INIT 进程是由 Linux 内核引导的,是系统中的第一个进程,是系统其他进程的祖先进程,其进程号(PID)永远为 1。

INIT 进程在运行时将读取系统引导配置文件 /etc/inittab 中的信息。这些信息包括默认的运行级别和由 INIT 启动的进程。

cat /etc/inittab
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $

# The default runlevel.
id:2:initdefault:

# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS

# What to do in single-user mode.
~~:S:wait:/sbin/sulogin

# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.

l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin

# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

# Action on special keypress (ALT-UpArrow).
#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."

# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop

# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# :::
#
# Note that on most Debian systems tty7 is used by the X Window System,
# so if you want to add more getty's go ahead but skip tty7 if you run X.
#
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

以 # 开头的行为注释行

每一行包括如下四个字段(每个字段用“:”间隔):

id : runlevels : action : process

文件 /etc/inittab 的字段说明

id

该字段是各有效行的标识符。对定义 getty 的各行来说,该标识符指定 getty 运行的终端(即设备文件 /dev/tty 之后的数字字符);对其他行来说,除了有长度限制外没有特殊要求,但该字段在整个文件中必须唯一。

runlevels

指定运行级别,各运行级别由单个的数字表示,可以指定多个运行级别,但不能包含任何间隔符。

action

指定运行状态,可以有如下的取值:

initdefault — 指定启动后所进入的运行级别,process 字段将被忽略,默认值为 2

sysinit — 在系统启动时执行初始化

wait — 执行下一个字段指定的命令,并等待其结束再运行其他命令

respawn — 当下一个字段指定的命令结束后,重新运行该命令(如控制台登录程序 getty)

ctrlaltdel — 当按下Ctrl+Alt+Del组合键时执行下一个字段指定的命令

powerwait — 当出现电源错误时执行下一个字段指定的命令,并等待其结束

powerfailnow — 当出现电源错误时执行下一个字段指定的命令,不等待其结束

powerokwait — 当电源恢复时执行下一个字段指定的命令

优化Linux启动速度

要想提速可以从这几个方面考虑

1 了解linux的启动过程 然后针对自己的电脑取舍

2 了解自己的计算机硬件 重新编译内核 只选择自己需要的模块

3 了解x-window工作方式 优化x-window

4 不要安装不需要的软件 能省就省 做到系统最小化 功能最大化

2008年4月24日木曜日

命令行配置ubuntu网络

为网卡配置DHCP地址:
如果你想配置DHCP地址,你需要编辑/etc/network/interfaces,并输入以下几行(假设你的网卡是eth0):
sudo vi /etc/network/interfaces

# The primary network interface - use DHCP to find our address
auto eth0
iface eth0 inet dhcp //指定为dhcp

在输入这几行后,你需要通过以下命令重新启动你的网络设备:
sudo /etc/init.d/networking restart

为网卡配置静态IP
如果你想配置静态IP地址,你需要编辑/etc/network/interfaces,并输入以下几行(假设你的网卡是eth0):
sudo vi /etc/network/interfaces

# The primary network interface
auto eth0
iface eth0 inet static //指定为static
address 192.168.3.90 //IP地址
gateway 192.168.3.1 //网关
netmask 255.255.255.0 //子网掩码
network 192.168.3.0 //这个……网络?
broadcast 192.168.3.255 //广播

在输入这几行后,你需要通过以下命令重新启动你的网络设备:
sudo /etc/init.d/networking restart

设置第二个IP地址或虚拟IP
如果你是一个服务器管理员或者只是普通用户,有时你需要为系统指派第二个IP,那么你可以这样做,同样编辑/etc/network/interfaces文件(假设你的网卡是eth0):

sudo vi /etc/network/interfaces

auto eth0:1
iface eth0:1 inet static
address 192.168.1.60
netmask 255.255.255.0
network x.x.x.x
broadcast x.x.x.x
gateway x.x.x.x


在输入这几行后,你需要通过以下命令重新启动你的网络设备:
sudo /etc/init.d/networking restart

设置Ubuntu系统的hostname
使用以下命令格式来改系统的hostname,或者直接编辑/etc/hostname
sudo hostname newname

设置DNS
sudo vi /etc/resolv.conf

enter the following details

search test.com
nameserver 192.168.3.2

2007年12月15日土曜日

段错误不产生core文件问题的解决

检查以后发现原因是 core 文件最大尺寸(用 ulimit -c 查看)是 0,把它设置成非 0 值就可以了,如:
ulimit -c 2048(设置 core 文件最大尺寸为 2048 blocks,1block=512bytes,因此这里设置的其实是 1MB)
ulimit -c unlimited(不限 core 文件尺寸)

2007年12月2日日曜日

在URXVT中使用LS命令时颜色无法显示的问题

装好URXVT后,发现在执行LS命令的时候,无法用颜色区分不同类型的文件。但在XTERM中却可以。调查后发现环境变量TERM被设置成了rxvt-unicode。而在/etc/DIR_COLORS文件中,没有相关的设定。加上下面一行后问题解决。
TERM rxvt-unicode

2007年12月1日土曜日

Linux常用命令

fc-list : 可用字体列表

理解 Linux 配置文件

本文说明了 Linux 系统的配置文件,在多用户、多任务环境中,配置文件控制用户权限、系统应用程序、守护进程、服务和其它管理任务。这些任务包括管理用户帐号、分配磁盘配额、管理电子邮件和新闻组,以及配置内核参数。本文还根据配置文件的使用和其所影响的服务的情况对目前 Red Hat Linux 系统中的配置文件进行了分类。
介绍

每 个 Linux 程序都是一个可执行文件,它含有操作码列表,CPU 将执行这些操作码来完成特定的操作。例如,ls 命令是由 /bin/ls 文件提供的,该文件含有机器指令的列表,在屏幕上显示当前目录中文件的列表时需要使用这些机器指令。几乎每个程序的行为都可以通过修改其配置文件来按照您 的偏好或需要去定制。

Linux 中有没有一个标准的配置文件格式?

一句话,没有。不熟悉 Linux 的用户(一定)会感到沮丧,因为每个配置文件看起来都象是一个要迎接的新挑战。在 Linux 中,每个程序员都可以自由选择他或她喜欢的配置文件格式。可以选择的格式很多,从 /etc/shells 文件(它包含被一个换行符分开的 shell 的列表),到 Apache 的复杂的 /etc/httpd.conf 文件。

什么是系统配置文件?

内核 本身也可以看成是一个“程序”。为什么内核需要配置文件?内核需要了解系统中用户和组的列表,进而管理文件权限(即根据权限判定特定用户 (UNIX_USERS)是否可以打开某个文件)。注意,这些文件不是明确地由程序读取的,而是由系统库所提供的一个函数读取,并被内核使用。例如,程序 需要某个用户的(加密过的)密码时不应该打开 /etc/passwd 文件。相反,程序应该调用系统库的 getpw() 函数。这种函数也被称为系统调用。打开 /etc/passwd 文件和之后查找那个被请求的用户的密码都是由内核(通过系统库)决定的。

除非另行指定,Red Hat Linux 系统中大多数配置文件都在 /etc 目录中。配置文件可以大致分为下面几类:

访问文件

/etc/host.conf 告诉网络域名服务器如何查找主机名。(通常是 /etc/hosts,然后就是名称服务器;可通过 netconf 对其进行更改)
/etc/hosts 包含(本地网络中)已知主机的一个列表。如果系统的 IP 不是动态生成,就可以使用它。对于简单的主机名解析(点分表示法),在请求 DNS 或 NIS 网络名称服务器之前,/etc/hosts.conf 通常会告诉解析程序先查看这里。
/etc/hosts.allow 请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。
/etc/hosts.deny 请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。

引导和登录/注销

/etc/issue & /etc/issue.net 这些文件由 mingetty(和类似的程序)读取,用来向从终端(issue)或通过 telnet 会话(issue.net)连接的用户显示一个“welcome”字符串。它们包括几行声明 Red Hat 版本号、名称和内核 ID 的信息。它们由 rc.local 使用。
/etc/redhat-release 包括一行声明 Red Hat 版本号和名称的信息。由 rc.local 使用。
/etc/rc.d/rc 通常在所有运行级别运行,级别作为参数传送。例如,要以图形(Graphics)模式(X-Server)引导机器,请在命令行运行下面的命令: init 5 。运行级别 5 表示以图形模式引导系统。
/etc/rc.d/rc.local 非正式的。可以从 rc、rc.sysinit 或 /etc/inittab 调用。
/etc/rc.d/rc.sysinit 通常是所有运行级别的第一个脚本。
/etc/rc.d/rc/rcX.d 从 rc 运行的脚本( X 表示 1 到 5 之间的任意数字)。这些目录是特定“运行级别”的目录。当系统启动时,它会识别要启动的运行级别,然后调用该运行级别的特定目录中存在的所有启动脚本。例 如,系统启动时通常会在引导消息之后显示“entering run-level 3”的消息;这意味着 /etc/rc.d/rc3.d/ 目录中的所有初始化脚本都将被调用。

文件系统

内核提供了一个接口,用来显示一些它的数据结构,这些数据结构对于决 定诸如使用的中断、初始化的设备和内存统计信息之类的系统参数可能很有用。这个接口是作为一个独立但虚拟的文件系统提供的,称为 /proc 文件系统。很多系统实用程序都使用这个文件系统中存在的值来显示系统统计信息。例如,/proc/modules 文件列举系统中当前加载的模块。lsmod 命令读取此信息,然后将其以人们可以看懂的格式显示出来。下面表格中指定的 mtab 文件以同样的方式读取包含当前安装的文件系统的 /proc/mount 文件。

/etc/mtab 这将随着 /proc/mount 文件的改变而不断改变。换句话说,文件系统被安装和卸载时,改变会立即反映到此文件中。
/etc/fstab 列举计算机当前“可以安装”的文件系统。这非常重要,因为计算机引导时将运行 mount -a 命令,该命令负责安装 fstab 的倒数第二列中带有“1”标记的每一个文件系统。
/etc/mtools.conf DOS 类型的文件系统上所有操作(创建目录、复制、格式化等等)的配置。

系统管理

/etc/group 包含有效的组名称和指定组中包括的用户。单一用户如果执行多个任务,可以存在于多个组中。例如,如果一个“用户”是“project 1”工程组的成员,同时也是管理员,那么在 group 文件中他的条目看起来就会是这样的: user: * : group-id : project1
/etc/nologin 如果有 /etc/nologin 文件存在,login(1) 将只允许 root 用户进行访问。它将对其它用户显示此文件的内容并拒绝其登录。
etc/passwd 请参阅“man passwd”。它包含一些用户帐号信息,包括密码(如果未被 shadow 程序加密过)。
/etc/rpmrc rpm 命令配置。所有的 rpm 命令行选项都可以在这个文件中一起设置,这样,当任何 rpm 命令在该系统中运行时,所有的选项都会全局适用。
/etc/securetty 包含设备名称,由 tty 行组成(每行一个名称,不包括前面的 /dev/),root 用户在这里被允许登录。
/etc/usertty
/etc/shadow 包含加密后的用户帐号密码信息,还可以包括密码时效信息。包括的字段有:
登录名
加密后的密码
从 1970 年 1 月 1 日到密码最后一次被更改的天数
距密码可以更改之前的天数
距密码必须更改之前的天数
密码到期前用户被警告的天数
密码到期后帐户被禁用的天数
从 1970 年 1 月 1 日到帐号被禁用的天数

/etc/shells 包含系统可用的可能的“shell”的列表。
/etc/motd 每日消息;在管理员希望向 Linux 服务器的所有用户传达某个消息时使用。

联网

/etc/gated.conf gated 的配置。只能被 gated 守护进程所使用。
/etc/gated.version 包含 gated 守护进程的版本号。
/etc/gateway 由 routed 守护进程可选地使用。
/etc/networks 列举从机器所连接的网络可以访问的网络名和网络地址。通过路由命令使用。允许使用网络名称。
/etc/protocols 列举当前可用的协议。请参阅 NAG(网络管理员指南,Network Administrators Guide)和联机帮助页。 C 接口是 getprotoent。绝不能更改。
/etc/resolv.conf 在程序请求“解析”一个 IP 地址时告诉内核应该查询哪个名称服务器。
/etc/rpc 包含 RPC 指令/规则,这些指令/规则可以在 NFS 调用、远程文件系统安装等中使用。
/etc/exports 要导出的文件系统(NFS)和对它的权限。
/etc/services 将网络服务名转换为端口号/协议。由 inetd、telnet、tcpdump 和一些其它程序读取。有一些 C 访问例程。
/etc/inetd.conf inetd 的配置文件。请参阅 inetd 联机帮助页。包含每个网络服务的条目,inetd 必须为这些网络服务控制守护进程或其它服务。注意,服务将会运行,但在 /etc/services 中将它们注释掉了,这样即使这些服务在运行也将不可用。格式为:
/etc/sendmail.cf 邮件程序 sendmail 的配置文件。比较隐晦,很难理解。
/etc/sysconfig/network 指出 NETWORKING=yes 或 no。至少由 rc.sysinit 读取。
/etc/sysconfig/network-scrīpts/if* Red Hat 网络配置脚本。

系统命令

系统命令要独占地控制系统,并让一切正常工作。所有如 login(完成控制台用户身份验证阶段)或 bash(提供用户和计算机之间交互)之类的程序都是系统命令。因此,和它们有关的文件也特别重要。这一类别中有下列令用户和管理员感兴趣的文件。

/etc/lilo.conf 包含系统的缺省引导命令行参数,还有启动时使用的不同映象。您在 LILO 引导提示的时候按 Tab 键就可以看到这个列表。
/etc/logrotate.conf 维护 /var/log 目录中的日志文件。
/etc/identd.conf identd 是一个服务器,它按照 RFC 1413 文档中指定的方式实现 TCP/IP 提议的标准 IDENT 用户身份识别协议。identd 的操作原理是查找特定 TCP/IP 连接并返回拥有此连接的进程的用户名。作为选择,它也可以返回其它信息,而不是用户名。请参阅 identd 联机帮助页。
/etc/ld.so.conf “动态链接程序”(Dynamic Linker)的配置。
/etc/inittab 按年代来讲,这是 UNIX 中第一个配置文件。在一台 UNIX 机器打开之后启动的第一个程序是 init,它知道该启动什么,这是由于 inittab 的存在。在运行级别改变时,init 读取 inittab,然后控制主进程的启动。
/etc/termcap 一个数据库,包含所有可能的终端类型以及这些终端的性能。

守护进程

守护进程是一种运行在非交互模式下的程序。一般来说,守护进程任务是和联网区域有关的:它们等待连接,以便通过连接提供服务。Linux 可以使用从 Web 服务器到 ftp 服务器的很多守护进程。

/etc/syslogd.conf syslogd 守护进程的配置文件。syslogd 是一种守护进程,它负责记录(写到磁盘)从其它程序发送到系统的消息。这个服务尤其常被某些守护进程所使用,这些守护进程不会有另外的方法来发出可能有问 题存在的信号或向用户发送消息。
/etc/httpd.conf Web 服务器 Apache 的配置文件。这个文件一般不在 /etc 中。它可能在 /usr/local/httpd/conf/ 或 /etc/httpd/conf/ 中,但是要确定它的位置,您还需要检查特定的 Apache 安装信息。
/etc/conf.modules or /etc/modules.conf kerneld 的配置文件。有意思的是,kerneld 并不是“作为守护进程的”内核。它其实是一种在需要时负责“快速”加载附加内核模块的守护进程。

用户程序

在 Linux(和一般的 UNIX)中,有无数的“用户”程序。最常见的一种用户程序配置文件是 /etc/lynx.cfg。这是著名的文本浏览器 lynx 的配置文件。通过这个文件,您可以定义代理服务器、要使用的字符集等等。下面的代码样本展示了 lynx.cfg 文件的一部分,修改这部分代码可以改变 Linux 系统的代理服务器设置。缺省情况下,这些设置适用于在各自的 shell 中运行 lynx 的所有用户,除非某个用户通过指定 --cfg = "mylynx.cfg" 重设了缺省的配置文件。


/etc/lynx.cfg 中的代理服务器设置
.h1 proxy
.h2 HTTP_PROXY
.h2 HTTPS_PROXY
.h2 FTP_PROXY
.h2 GOPHER_PROXY
.h2 NEWS_PROXY
.h2 NNTP_PROXY
# Lynx version 2.2 and beyond supports the use of proxy servers that can act as
# firewall gateways and caching servers. They are preferable to the older
# gateway servers. Each protocol used by Lynx can be mapped separately using
# PROTOCOL_proxy environment variables (see Lynx Users Guide). If you have
# not set them externally, you can set them at run time via this configuration file.
# They will not override external settings. The no_proxy variable can be used
# to inhibit proxying to selected regions of the Web (see below). Note that on
# VMS these proxy variables are set as process logicals rather than symbols, to
# preserve lowercasing, and will outlive the Lynx image.
#
.ex 15
http_proxy:http://proxy3.in.ibm.com:80/
ftp_proxy:http://proxy3.in.ibm.com:80/
#http_proxy:http://penguin.in.ibm.com:8080
#ftp_proxy:http://penguin.in.ibm.com:8080/
.h2 NO_PROXY
# The no_proxy variable can be a comma-separated list of strings defining
# no-proxy zones in the DNS domain name space. If a tail substring of the
# domain-path for a host matches one of these strings, transactions with that
# node will not be proxied.
.ex
no_proxy:demiurge.in.ibm.com, demiurge

更改配置文件

在更改配置文件时,如果程序不是由系统管理员或内核控制的,就要确保重新启动过使用该配置的程序。普通用户通常没有启动或停止系统程序和/或守护进程的权限。

内核

更 改内核中的配置文件会立即影响到系统。例如,更改 passwd 文件以增加用户将立即使该用户变为可用。而且任何 Linux 系统的 /proc/sys 目录中都有一些内核可调参数。只有超级用户可以得到对所有这些文件的写访问权力;其它用户只有只读访问权力。此目录中文件的分类的方式和 Linux 内核源代码的分类方式一样。此目录中的每个文件都代表一个内核数据结构,这些数据结构可以被动态地修改,从而改变系统性能。

注意:在更改其中任何文件的任何值之前,您应该确保自己全面了解该文件,以避免对系统造成不可修复的损害。
/proc/sys/kernel/ 目录中的文件

文件名 描述
threads-max 内核可运行的最大任务数。
ctrl-alt-del 如果值为 1,那么顺序按下这几个键将“彻底地”重新引导系统。
sysrq 如果值为 1,Alt-SysRq 则为激活状态。
osrelease 显示操作系统的发行版版本号
ostype 显示操作系统的类型。
hostname 系统的主机名。
domainname 网络域,系统是该网络域的一部分。
modprobe 指定 modprobe 是否应该在启动时自动运行并加载必需的模块。

守护进程和系统程序

守 护进程是永远运行在后台的程序,它默默地执行自己的任务。常见的守护进程有 in.ftpd(ftp 服务器守护进程)、in.telnetd(telnet 服务器守护进程)和 syslogd(系统日志记录守护进程)。有些守护进程在运行时会严密监视配置文件,在配置文件改变时就会自动重新加载它。但是大多数守护进程并不会自动 重新加载配置文件。我们需要以某种方式“告诉”这些守护进程配置文件已经被发生了改变并应该重新加载。可以通过使用服务命令重新启动服务来达到这个目的 (在 Red Hat Linux 系统上)。

例如,如果我们更改了网络配置,就需要发出:
service network restart 。

注意:这些服务最常见的是 /etc/rc.d/init.d/* 目录中存在的脚本,在系统被引导时由 init 启动。所以,您也可以执行如下操作来重新启动服务:
/etc/rc.d/init.d/ start | stop | status
start、stop 和 status 是这些脚本接受的输入值,用来执行操作。

用户程序

用 户或系统程序在每次启动时都会读取其配置文件。尽管如此,请记住,有些系统程序在计算机打开时情况不一样,它们的行为依赖于在 /etc/ 中的配置文件中读到的内容。所以,用户程序第一次启动时将从 /etc/ 目录中存在的文件读取缺省配置。然后,用户可以通过使用 rc 和 .(点)文件来定制程序,正如下面一节所示。
用户配置文件:.(点)文件和 rc 文件

我们已经看到怎样容易地配置程序。但是如 果有的人不喜欢在 /etc/ 中配置程序的方式该怎么办呢?“普通”用户不能简单地进入 /etc 然后更改配置文件;从文件系统的角度来看,配置文件的所有者是 root 用户!这就是大多数用户程序都定义两个配置文件的原因:第一个是“系统”级别的,位于 /etc/;另一个属于用户“专用”,可以在他或她的主目录中找到。

例如,我在我的系统中安装了非常有用的 wget 实用程序。/etc/ 中有一个 /etc/wgetrc 文件。在我的主目录中,有一个名为 .wgetrc 的文件,它描述了我定制的配置(只有在我,也就是用户运行 wget 命令时,才会加载这个配置文件)。其它用户在他们自己的主目录(/home/other)中也可以有 .wgetrc 文件;当然,只有这些用户运行 wget 命令时,才会读取这个文件。换句话说,/etc/wgetrc 文件为 wget 提供了“缺省”值,而 /home/xxx/.wgetrc 文件列举了某个用户的“定制项”。重要的是这只是“一般规则”,并非所有情况都如此。例如,一个象 pine 一样的程序,在 /etc/ 中并没有任何文件,它只在用户主目录中有一个定制配置文件,名为 .pinerc。其它程序可能只有 /etc/ 中的缺省配置文件,而且可能不允许用户“定制”这些配置文件(/etc 目录中只有少数 config. 文件是这种情况)。

通常使用的 rc 和 .(点)文件

文件名 描述
~/.bash_login 请参考“man bash”。如果 ~/.bash_profile 不存在,bash 则将 ~/.bash_login 作为 ~/.bash_profile 处理。
~/.bash_logout 请参考“man bash”。在退出时由 bash 登录 shell 引用。
~/.bash_profile 由 bash 登录 shell 引用 /etc/profile 之后引用。
~/.bash_history 先前执行的命令的列表。
~/.bashrc 请参考“man bash”。由 bash 非登录交互式 shell 引用(没有其它文件)。除非设置了 BASH_ENV 或 ENV,非交互式 shell 不引用任何文件。
~/.emacs 启动时由 emac 读取。
~/.forward 如果这里包含一个电子邮件地址,那么所有发往 ~ 的所有者的邮件都会被转发到这个电子邮件地址。
~/.fvwmrc ~/.fvwm2rc fvwm 和 fvwm2(基本的 X Window 管理器)的配置文件。
~/.hushlogin 请参考“man login”。引起“无提示”登录(没有邮件通知、上次登录信息或者 MOD 信息)。
~/.mail.rc 邮件程序的用户初始化文件。
~/.ncftp/ ncftp 程序的目录;包含书签、日志、宏、首选项和跟踪信息。请参阅 man ncftp。ncftp 的目的是为因特网标准文件传输协议(Internet standard File Transfer Protocol)提供一个强大而灵活的接口。它旨在替换系统所使用的标准的 ftp 程序。
~/.profile 请参考“man bash”。如果 ~/.bash_profile 和 ~/.bash_login 文件不存在,bash 则将 ~/.profile 作为 ~/.bash_profile 处理,并被其它继承 Bourn 的 shell 使用。
~/.pinerc Pine 配置
~/.muttrc Mutt 配置
~/.exrc 这个文件可以控制 vi 的配置。
示例:set ai sm ruler
在此文件中写入上面一行会让 vi 设置自动缩进、匹配括号、显示行号和行-列这几个选项。
~/.vimrc 缺省的“Vim”配置文件。和 .exrc 一样。
~/.gtkrc GNOME 工具包(GNOME Toolkit)。
~/.kderc KDE 配置。
~/.netrc ftp 缺省登录名和密码。
~/.rhosts 由 r- 工具(如 rsh、rlogin 等等)使用。因为冒充主机很容易,所以安全性非常低。

必须由用户(~/ 的所有者)或超级用户拥有。
列出一些主机,用户可以从这些主机访问该帐号。
如果是符号链接则被忽略。

~/.rpmrc 请参阅“man rpm”。如果 /etc/rpmrc 不存在则由 rpm 读取。
~/.signature 消息文本,将自动附加在从此帐号发出的邮件末尾。
~/.twmrc twm( The Window Manager)的配置文件。
~/.xinitrc 启动时由 X 读取(而不是由 xinit 脚本读取)。通常会启动一些程序。
示例:exec /usr/sbin/startkde
如果该文件中存在上面这行内容,那么在从这个帐号发出 startx 命令时,这一行就会启动“KDE 视窗管理器”(KDE Window Manager)。
~/.xmodmaprc 此文件被传送到 xmodmap 程序,而且可以被命名为任何文件(例如 ~/.Xmodmap 和 ~/.keymap.km)。
~/.xserverrc 如果 xinit 可以找到要执行的 X,xinit 就会将该文件作为 X 服务器运行。
~/News/Sent-Message-IDs gnus 的缺省邮件历史文件。
~/.Xauthority 由 xdm 程序读和写,以处理权限。请参阅 X、xdm 和 xauth 联机帮助页。
~/.Xdefaults, ~/.Xdefaults-hostname 在主机 hostname 的启动过程中由 X 应用程序读取。如果找不到 -hostname 文件,则查找 .Xdefaults 文件。
~/.Xmodmap 指向 .xmodmaprc;Red Hat 有使用这个名称的 .xinitrc 文件。
~/.Xresources 通常是传送到 xrdb 以加载 X 资源数据库的文件的名称,旨在避免应用程序需要读取一个很长的 .Xdefaults 文件这样的情况。(有些情况曾经使用了 ~/.Xres。)
~/mbox 用户的旧邮件。

2007年11月27日火曜日

VIM(GVIM)常用命令

在 文 本 中 查 找 一 个 单 词
假设你在文本中看到一个单词 "TheLongFunctionName" 而你想找到下一个相同的单词。
你可以输入 "/TheLongFunctionName",但这要输入很多东西。而且如果输错了,Vim 是
不可能找到你要找的单词的。
有一个简单的方法:把光标移到那个单词下面使用 "*" 命令。Vim 会取得光标上的
单词并把它作为被查找的字符串。
"#" 命令在反向完成相同的功能。你可以在命令前加一个计数:"3*" 查找光标下单
词第三次出现的地方。

查 找 整 个 单 词
如果你输入 "/the",你也可能找到 "there"。要找到以 "the" 结尾的单词,可以用:
/the\> "\>" 是一个特殊的记号,表示只匹配单词末尾。类似地,"\<" 只匹配单词的开头。 这样,要匹配一个完整的单词 "the",只需: /\ 这不会匹配 "there" 或者 "soothe"。注意 "*" 和 "#" 命令也使用了 "词首" 和
"词尾" 标记来匹配整个单词 (要部分匹配,使用 "g*" 和 "g#")

你可以用如下命令取得所有的标记的列表:
:marks 你会注意到有一些特殊的标记,包括:
' 跳转前的光标位置
" 最后编辑的光标位置
[ 最后修改的开始位置
] 最后修改的结束位置

快 捷 键
有些 "操作符-动作" 命令由于经常被使用,所以被设置为单字符命令:
x 表示 dl (删除当前光标下的字符)
X 表示 dh (删除光标左边的字符)
D 表示 d$ (删除到行尾)
C 表示 c$ (修改到行尾)
s 表示 cl (修改一个字符)
S 表示 cc (修改一整行)

在 什 么 地 方 加 入 计 数 前 缀
命令 "3dw" 和 "d3w" 都是删除 3 个单词。如果你非要寻根问底,那么:"3dw" 表示删
除一个单词 3 次,而 "d3w" 表示删除三个单词一次。这是一个没有分别的分别。实际上
你可以放两个计数前缀,例如,"3d2w" 删除两个单词三次,共计六个单词。

可视模式
你可以用 "v" 命令启动可视模式
如果你想对整行做操作,可以使用 "V" 命令来启动可视模式。
如果你要处理一个矩形块内的文本,可以使用 CTRL-V 启动可视模式。这在处理表格时非
常有用。

移 动 到 另 一 端
如果你在可视模式下选中了一些文字,然后你又发现你需要改变被选择的文字的另一端,
用 "o" 命令即可 (提示:"o" 表示 other end),光标会移动到被选中文字的另一端,现
在你可以移动光标去改变选中文字的开始点了。再按 "o" 光标还会回到另一端。
当使用列块可视模式的时候,你会有四个角,"o" 只是把你移到对角上。而用 "O" 则能
移到同一行的另一个角上。
备注: "o" 和 "O" 在可视模式下与在普通模式下的作用有很大的不同;在普通模式下,
它们的作用是在光标后或前加入新的一行。

拷贝文本
注意:"yw" 命令包括单词后面的空白字符。如果你不想要这个字符,改用 "ye" 命令。
"yy" 命令拷贝一整行,就像 "dd" 删除一整行一样。出乎意料地是,"D" 删除到行尾而
"Y" 却是拷贝一整行。要注意这个区别!"y$" 拷贝到行尾。

使用剪贴板
如果你用的不是 GUI,或者你根本不喜欢用菜单,你只能用其它办法了。你还是可以用普
通的 "y" (yank) 和 "p" (put) 命令,但在前面必须加上 "* (一个双引号加一个星
号)。例如,要拷贝一行到剪贴板中:
"*yy 要粘贴回来:
"*p 这仅在支持剪贴板的 Vim 版本中才能工作。

文本对象
如果你在一个单词的中间而又想删掉这个单词,在你用 "dw" 前,你必须先移到这个单词
的开始处。这里还有一个更简单的方法:"daw"。
"daw" 的 "d" 是删除操作符。"aw" 是一个文本对象。提示:"aw" 表示 "A Word" (一个
单词),这样,"daw" 就是 "Delete A Word" (删除一个单词)。确切地说,该单词后的空
格字符也被删除掉了。

使用文本对象是 Vim 中执行修改的第三种方法。我们已经有 "操作符-动作" 和可视模
式两种方法了。现在我们又有了 "操作符-文本对象"。
这种方法与 "操作符-动作" 很相似,但它不是操作于从当前位置到移动目标间的内
容,而是对光标所在位置的 "文本对象" 进行操作。文本对象是作为一个整体来处理的。
现在光标在对象中的位置无关紧要。

用 "cis" 可以改变一个句子。看下面的句子:

Hello there. This
is an example. Just
some text.

移动到第二行的开始处。现在使用 "cis":

Hello there. Just
some text.

现在你输入新的句子 "Another line.":

Hello there. Another line. Just
some text.

"cis" 包括 "c" (change,修改) 操作符和 "is" 文本对象。这表示 "Inner Sentence"
(内含句子)。还有一个文本对象是 "as",区别是 "as" 包括句子后面的空白字符而 "is"
不包括。如果你要删除一个句子,而且你还想同时删除句子后面空白字符,就用 "das";
如果你想保留空白字符而替换一个句子,则使用 "cis"。

你还可以在可视模式下使用文本对象。这样会选中一个文本对象,而且继续留在可视模
式,你可以继续多次执行文本对象命令。例如,先用 "v" 启动可视模式,再用 "as" 就
可以选中一个句子。现在重复执行 "as",就会继续选中更多的句子。最后你可以使用一
个操作符去处理这些被选中的句子。

你可以在这里找到一个详细的文本对象的列表:|text-objects|。
动作和操作符

动作命令出现在操作符之后,从而使操作符作用于被该动作所跨越的文本之上。也就 是,在动作之前和之后的光标位置之间的文本。一般的,操作符用来删除或者改变文本。 下面列出所有的操作符: |c| c 修改 (change)
|d| d 删除 (delete)
|y| y 抽出 (yank) 到寄存器 (不改变文本)
|~| ~ 变换大小写 (只有当 'tildeop' 置位时有效)
|g~| g~ 变换大小写
|gu| gu 变为小写
|gU| gU 变为大写
|!| ! 通过外部程序过滤
|=| = 通过 'equalprg' (若为空,C-indenting) 过滤
|gq| gq 文本排版
|g?| g? ROT13 编码
|>| > 右移
|<| < 左移 |zf| zf 定义折叠
|g@| g@ 调用 'operatorfunc' 选项定义的函数
预 定 义 标 记
当你跳转到另一个文件后,有两个预定义的标记非常有用:
`" 这个标记使你跳转到你上次离开这个文件时的位置。
另一个标记记住你最后一次修改文件的位置:
`.
假设你在编辑 "one.txt",在文件中间某个地方你用 "x" 删除一个字符,接着用 "G" 命
令移到文件末尾,然后用 "w" 存盘。然后你又编辑了其它几个文件。你现在用 ":edit
one.txt" 回到 "one.txt"。如果现在你用 `",Vim 会跳转到文件的最后一行;而用 `.
则跳转到你删除字符的地方。即使你在文件中移动过,但在你修改或者离开文件前,这两
个标记都不会改变。

文 件 标 记

在第四章,我们介绍过使用 "mx" 命令在文件中增加标记,那只在一个文件中有效。如果
你编辑另一个文件并在那里加了标记,这些标记都是这个文件专用的。这样,每个文件都
有一个自己的标记集,并只能在该文件中使用。
到此为止,我们都用小写字母的标记。实际上还可以使用大写字母标记,这种标记是
全局的,它们可以在任何文件中使用。例如,你在编辑一个文件 "foo.txt"。在文件的中
间 (50%) 并建立一个 J 标记 (J 表示甲):

50%mJ
现在编辑文件 "bar.txt" 并在文件的最后一行放一个标记 Y (Y 表示乙):

GmY
现在你可以使用 "`J" 命令跳回到 foo.txt 的中间。或者在另一个文件中输入 "`Y" 跳
回到 bar.txt 的末尾。

文件标记会被一直记住直到被重新定义。这样,你可以在一个文件中留下一个标记,然后
任意做一段时间的编辑,最后用这个标记跳回去。
让文件标记符和对应的位置建立一些关系常常是很有用的。例如,用 H 表示头文件
(Head File),M 表示 Makefile 而 C 表示 C 的代码文件。

要知道一个标记在什么地方,在 ":marks" 命令中加上标记名作为参数即可:

:marks M
你还可以带多个参数:

:marks MCP
别忘了你还可以 CTRL-OCTRL-I 在整个跳转序列中前后跳转。
用 vimdiff 显示文件差异

有一种特殊的启动 Vim 的方法可以用来显示两个文件的差异。让我们打开一个 "main.c" 并插入一些字符。在设置了 'backup' 选项的情况下保存这个文件,以便产生 "main.c~" 备份文件。 在命令行中输入如下命令:(不是在 Vim 中) vimdiff main.c~ main.c Vim 会用垂直分割的方式打开两个文件。你只能看到你修改过的地方和上下几行的地方。
折 叠 栏

每个窗口在左边都有一个颜色略有不同的显示栏,图中标识为 "VV"。你会发现每个折叠
在那个位置都有一个加号。把鼠标移到那里并按左键可以打开那个折起,从而让你看到里
面的内容。
对于打开的折叠,折叠栏上会出现一个减号。如果你单击那个减号,折叠会被重新关
闭。
当然,这只能在你有鼠标的情况下使用。如果你没有,可以用 "zo" 打开一个折叠。
关闭使用 "zc"。

用 Vim 做 比 较

启动比较模式的另一种方法从 Vim 内部开始:编辑 "main.c" 文件,然后分割窗口显示
区别:

:edit main.c
:vertical diffsplit main.c
":vertical" 命令使窗口用垂直的方式分割。如果你不写这个命令,结果会变成水平分
割。

如果你有一个当前文件的补丁或者 diff 文件,你可以用第三种方法启动比较模式:先编
辑这个文件,然后告诉 Vim 补丁文件的名称:

:edit main.c
:vertical diffpatch main.c diff
警告:补丁文件中必须仅包括为一个目标文件所做的补丁,否则你可能会得到一大堆错误
信息。还可能有些你没打算打补丁的文件也被打了补丁。
补丁功能只改变内存中的文件备份,不会修改你硬盘上的文件 (除非你决定写入改
动)。

滚 动 绑 定

当文件中有很多改动时,你可以用通常的方式滚动屏幕。Vim 会尽可能保持两个文件对
齐,以便你可以并排看到文件的区别。
如果暂时想关闭这个特性,使用如下命令:

:set noscrollbind

跳 转 到 修 改 的 地 方

如果你通过某种方法取消了折叠功能,可能很难找到有改动的地方。使用如下命令可以跳
转到下一个修改点:

]c
反向跳转为:

[c
加上一个计数前缀可以跳得更远。

消 除 差 异

你可以把文本从一个窗口移到另一个,并以此来消除差异,或者为其中一个文件中增加几
行。Vim 有时可能无法及时更新高亮显示。要修正这种问题,使用如下命令:

:diffupdate
要消除差异,你可以把一个高亮显示的块从一个窗口移动到另一个窗口。以上面的
"main.c" 和 "main.c~" 为例,把光标移到左边的窗口,在另一个窗口中被删除的行的位
置,执行如下命令:

:dp
这将把文字从左边拷到右边,从而消除两边的差异。"dp" 代表 "diff put"。
你也可以反过来做:把光标移到右边的窗口,移到被 "改动" 了的行上,然后执行
如下命令:

:do
这把文本从左边拷到右边,从而消除差异。
由于两个文件已经没有区别了,Vim 会把所有文字全部折叠起来。"do" 代表 "diff
obtain"。本来用 "dg" (diff get) 会更好。可是它已经有另外的意思了 ("dgg" 删除从
光标为止到首行的所有文本)。
标签页
假设你正在编辑文件 "thisfile"。下面的命令可以建立新的标签页:

:tabedit thatfile
这会在一个窗口中编辑文件 "thatfile",这个窗口会占满整个 Vim 窗口。你会注意到在
顶部有一个含有两个文件名的横条:
你可以通过单击顶端的标签切换标签页。如果没有鼠标或者不想用它,可以使用 "gt" 命
令。助记符:Goto Tab。

现在,让我们通过下面的命令建立另一个标签页:

:tab split
这会建立一个新的标签页,包含一个窗口,编辑和刚才所在窗口中的缓冲区相同的缓冲
区:
在任何打开窗口的 Ex 命令前面,你都可以放上 ":tab"。这个窗口在新标签页中打开。
另一个例子:

:tab help gt
它将在新的标签页中显示关于 "gt" 的帮助。

使用标签页可以完成更多的工作:

- 在末尾标签后面的空白处单击鼠标
选择下个标签页,同 "gt"。

- 在右上角的 "X" 处单击鼠标
关闭当前标签页,除非当前标签页中的改变没有保存。

- 在标签行上双击鼠标
建立新标签页。

- "tabonly" 命令
关闭除了当前标签页以外的所有标签页,除非其它标签页中的改变没有保存。

关于标签页更多的信息,参见 |tab-page|。
反转行顺序

|:global| 命令可以和 |:move| 命令联用,将所有行移动到文件首部。结果是文件被按 行反转了次序。命令是: :global/^/m 0 缩写: :g/^/m 0 正则表达式 "^" 匹配行首 (即使该行是一个空行)。|:move| 命令将匹配的行移动到那个 神秘的第 0 行之后。这样匹配的行就成了文件中的第一行。由于 |:global| 命令不会被 改变了的行号搞混,该命令继续匹配文件中剩余的行并将它们一一变为首行。 这对一个行范围同样有效。先移动到第一行上方并做标记 't' (mt)。然后移动到范围的 最后一行并键入: :'t+1,.g/^/m 't

单词统计

有时你要写一些有最高字数限制的文字。Vim 可以帮你计算字数。 如果你需要统计的是整个文件的字数,可以用这个命令:

g CTRL-G

不要在 "g" 后面输入一个空格,这里只是方便阅读。 它的输出是:

Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976 (译者注:中文是:
第 1/0 列; 第 141/157 行; 第 748/774 个词; 第 4489/4976 个字节 )

你可以看到你在第几个单词 (748) 上以及文件中的单词总数 (774)。
如果你要知道的是全文的一部分的字数,你可以移到该文本的开头,输入 "g CTRL-G",
然后移到该段文字的末尾,再输入 "g CTRL-G",最后心算出结果来。
这是一种很好的心 算练习,不过不是那么容易。比较方便的办法是使用可视模式,选中你要计算字数的文 本,然后输入 "g CTRL-G",结果将是: Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes (译者注:中文是: 选择了 5/293 行; 70/1884 个词; 359/10928 个字节 ) 要知道其它计算字数,行数和其它东西总数的方法,可以参见 |count-items|。
查阅 man 信息

编辑一个脚本文件或者 C 程序的时候,有时你会需要从 man 手册中查询某个命令或者函
数的用法 (使用 Unix 的情况下)。让我们先用一个简单的方法:把鼠标移到对应的单词
上然后输入:

K
Vim 会在对应的单词上执行外部命令:man。如果能找到相应的手册,那个手册页就会被
显示出来。它常常用 more 一类的程序显示页面。在手册滚动到文件末并回车,控制就会
回到 Vim 中。

这种方法的缺点是你不能同时查看手册和编辑文档。这里有一种办法可以把手册显示到一
个 Vim 的窗口中。首先,加载 man 文件类型的外挂:

:runtime! ftplugin/man.vim
如果你经常用到这种方法,可以把这个命令加到你的 vimrc 文件中。现在你可以用
":Man" 命令打开一个显示 man 手册的窗口了:

:Man csh
你可以在这个新的窗口中上下滚动,而手册的本文会用语法高亮的形式显示。这样,你可
以找到需要的地方,并用 CTRL-W w 跳转到原来的窗口中继续工作。
要指定手册的章节,可以在手册名称前面指定。例如,要找第三章的 "echo":

:Man 3 echo
要跳转到另一个由 "word(1)" 形式定义的手册,只要在上面敲 CTRL-]。无论怎样,
":Man" 命令总使用同一个窗口。

要显示当前光标下的单词的手册,这样:

\K
(如果你重定义了 ,用那个字符代替上面命令的反斜杠)。
例如,你想知道下面语句中的 "strstr()" 函数的返回值:

if ( strstr(input, "aap") == )

可以把光标移到 "strstr" 并输入 "\K"。手册使用的窗口会显示 strstr() 的信息。

使 用 XXD
一个真正的二进制编辑器用两种方式来显示文本: 二进制和十六进制格式。你可以在 Vim
里通过转换程序 "xxd" 来达到这效果。该程序是随 Vim 一起发布的。
首先以二进制方式编辑这个文件:

vim -b datafile
现在用 xxd 把这个文件转换成十六进制:

:%!xxd
文本看起来像这样:

0000000: 1f8b 0808 39d7 173b 0203 7474 002b 4e49 ....9..;..tt.+NI
0000010: 4b2c 8660 eb9c ecac c462 eb94 345e 2e30 K,.`.....b..4^.0
0000020: 373b 2731 0b22 0ca6 c1a2 d669 1035 39d9 7;'1.".....i.59.

现在你可以随心所欲地阅读和编辑这些文本了。 Vim 把这些信息当作普通文本来对待。
修改了十六进制部分并不导致可显示字符部分的改变,反之亦然。
最后,用下面的命令把它转换回来:

:%!xxd -r
只有十六进制部分的修改才会被采用。右边可显示文本部分的修改忽略不计。

欲知更多详情,参见 xxd 手册。

补 全 特 定 文 本

如果你知道你要找什么,那么你可以用这些命令来补全某种类型的文本:

CTRL-X CTRL-F 文件名
CTRL-X CTRL-L 整行
CTRL-X CTRL-D 宏定义 (包括包含文件里的)
CTRL-X CTRL-I 当前文件以及所包含的文件
CTRL-X CTRL-K 字典文件内的单词
CTRL-X CTRL-T 同义词词典文件内的单词
CTRL-X CTRL-] 标签
CTRL-X CTRL-V Vim 命令行
    CTRL-X CTRL-O 全能补全的热键

每个命令之后,CTRL-N 可以用来搜索下一个匹配,而 CTRL-P 则用于搜索前一个匹配。
重复一次插入
如果你按 CTRL-A,编辑器就把你上次在插入模式下输入的文本再输入一次。
比如,假定你有个文件,开头是这样的:

"file.h"
/* Main program begins */

你在第一行开始处插入 "#include ":

#include "file.h"
/* Main program begins */

你再用命令 "j^" 往下来到下一行的开始处。现在你开始插入一个新的 "#include" 行。
所以你键入:

i CTRL-A
结果就像下面这样:

#include "file.h"
#include /* Main program begins */

"#include " 被插入是因为 CTRL-A 会插入上次插入过的文本。现在你键入 "main.h"
以结束这一行:


#include "file.h"
#include "main.h"
/* Main program begins */

CTRL-@ 命令会完成 CTRL-A 的操作后退出插入模式。这是一个快速重复插入一模一样的
文本的一个方法。
从另一行拷贝
CTRL-Y 命令插入光标上方的字符。当你复制前一行文本的时候,这个命令很有用。例
如,你有这么一行 C 代码:

b_array[i]->s_next = a_array[i]->s_next;

现在你需要把这一行再键入一次,并以 "s_prev" 取代 "s_next"。换行以后,按 14 次
CTRL-Y,直到光标位于 "next" 的 "n" 上:

b_array[i]->s_next = a_array[i]->s_next;
b_array[i]->s_

现在你键入 "prev":

b_array[i]->s_next = a_array[i]->s_next;
b_array[i]->s_prev

继续按 CTRL-Y 直到下一个 "next":

b_array[i]->s_next = a_array[i]->s_next;
b_array[i]->s_prev = a_array[i]->s_

现在键入 "prev;" 以结束这一行。

CTRL-E 命令操作起来跟 CTRL-Y 一样,只不过它插入光标下方的字符。
插入一个寄存器内容
命令 CTRL-R {register} 插入寄存器里的内容。它的用处是让你不必键入长词。例如,
你要输入下面这些:

r = VeryLongFunction(a) + VeryLongFunction(b) + VeryLongFunction(c)

这个函数的定义见于另一个文件。编辑那个文件并把光标移到该函数名上,然后把文件名
摄入寄存器 v:

"vyiw
"v 指定寄存器,"yiw" 意思是拷贝一个词,不含空格 (yank-inner-word)。现在编辑那
个要插入一行代码的文件,先键入开头几个字符:

r =

现在用 CTRL-R v 来插入函数名:

r = VeryLongFunction

你接下来在函数名后面键入其它必要字符,然后再用两次 CTRL-R v。
你也可以用补全功能来完成同样的工作。但当你有好几个词,其开头几个字符都一样
的时候,寄存器就有用多了。

如果寄存器存放着诸如 或其它特殊字符,这些字符就被解释成好像它们本来是从键
盘键入的。如果你不要这样解释 (你确实要在文本中插入 ),那么要命令 CTRL-R
CTRL-R {register}

2007年11月26日月曜日

Xming使用技巧

  1. -[no]keyhook: 缺省状态下WINDOWS的一些特殊键或者键的组合会被XMING忽略掉(比如WIN键,ALT+TAB等)这个参数可以让你使用这些特殊键。

2007年11月21日水曜日

摸清Linux日志处理的来龙去脉

每个使用UNIX/LINUX的人都知道日志的用处,那你是否清楚LINUX这些日志信息处理的来龙去脉呢?

我们可以看到LINUX系统信息日志的途径基本有以下2种:

(1)dmesg查看----这个命令比较常见

(2)/var/log/下的文件

那下面我们就从这个2个途径着手,一步步的走下去.

(一)

首先,我们来看dmesg这个常见的命令背后隐藏的是什么!!

从LINUX提供的手册,我们可以得知一条最重要的信息dmesg是从kernel 的ring buffer(环缓冲区)中读取信息的.

(2)那什么是ring buffer呢?

在LINUX中,所有的系统信息(包内核信息)都会传送到ring buffer中.而内核产生的信息由printk()打印出来。系统启动时所看到的信息都是由该函数打印到屏幕中。 printk()打出的信息往往以 <0><2>...这的数字表明消息的重要级别。高于一定的优先级别会打印到屏幕上, 否则只会保留在系统的缓冲区中(ring buffer)。

至于dmesg具体是如何从ring buffer中读取的,大家可以看dmesg.c源代码.很短,比较容易读懂.

(二)

dmesg怎么搞的大家应该很明白了吧.至于/var/log/下的文件更是大家熟悉得不能再熟悉了!

(1)/var/log/..下为什么有这么多文件呢?

一句话解释: 是syslogd这个守护进程根据/etc/syslog.conf,将不同的服务产生的Log记录到不同的文件中.

这里的/etc/syslog.conf我就不细说了,很多这方面的信息(去查吧).

(2)既然知道了,/var/log/..是由syslogd这个守护进程产生的.那就再顺着这条线走下去.

LINUX系统启动后,由/etc/init.d/sysklogd先后启动klogd,syslogd两个守护进程。

其中klogd会通过syslog()系统调用或者读取proc文件系统来从系统缓冲区(ring buffer)中得到由内核printk()

发出的信息.而syslogd是通过klogd来读取系统内核信息.

我想至此,大家心理应该对log产生,读取等一系列的动作有所感觉.

总结

(1)所有系统信息是输出到ring buffer中去的.dmesg所显示的内容也是从ring buffer中读取的.

(2)LINUX系统中/etc/init.d/sysklogd会启动2个守护进程:Klogd&&Syslogd

(3)klogd是负责读取内核信息的,有2种方式:

syslog()系统调用(这个函数用法比较全,大家去MAN一下看看)

直接的对/proc/kmsg进行读取(再这提一下,/proc/kmsg是专门输出内核信息的地方)

(4)Klogd的输出结果会传送给syslogd进行处理,syslogd会根据/etc/syslog.conf的配置把log

信息输出到/var/log/下的不同文件中。