Ted's Blog

Happy coding

窗口管理器emerald的安装和使用

1。关闭metacity混合特性:
gconf-editor
找到apps--metacity--general--compositing_manager键,取消该选择。

2。开启compiz
compiz --replace;

3.启动emerald窗口管理器:
emerald --replace;

4。运行 系统-首选项-emerald theme manager 即可管理和使用已经下载的emerald主题。

5。让emerald成为默认窗口装饰器:
在CompizConfig设置管理器中将Window decorations中的Command改为emerald --replace。

emerge、eix、equery的基本用法

一、 emerge

1. 安装软件:
# emerge package_name

2. 更新软件并更新它直接依赖的其它软件包:
# emerge -u package_name

3. 更新一个软件并更新它依赖的软件包以及它们依赖的所有软件包, 这里大写的D相当于--deep。
# emerge -uD package_name

4. 软件包卸载:
# emerge -C package_name

5. 软件包搜索(只搜索名字):
# emerge -s key_word

6. 软件包查找(搜索内容):
# emerge -S key_word

7. 将本地软件列表与最新的portage树同步:
# emerge --sync && emerge portage

8. 只下载源码:
# emerge -f package_name

9. 更新系统中的所有软件:
# emerge -uD world

10. 查看一个预装包欲装的包:
# emerge -p package_name

11. 查看预装包总共有哪些 USE :
# emerge -pv package_name

二、eix
安装eix: emerge eix

1. 软件包搜索:
# eix key_word

2. 将本地软件列表与最新的portage树同步:
# eix-sync

、equery
equery可查看已安装包的信息,安装此工具: emerge gentoolkit

1. 列出所有已安装包:
# equery list 或简写:
# equery l

2. 查看已安装包装了哪些内容:
# equery files package_name 或简写:
# equery f package_name

3. 查看一个程序foo隶属于哪个包:
# equery belongs foo 或简写:
# equery b foo

4. 查看哪些包依赖于package_name:
# equery depends package_name 或简写:
# equery d package_name

5. 查看已安装包abc用了哪些USE:
# equery uses package_name 或简写:
# equery u package_name

使用dispatch-conf更新config文件

代码:
>>> No outdated packages were found on your system.


 * GNU info directory index is up-to-date.
 * IMPORTANT: 37 config files in /etc need updating.
 * IMPORTANT: 5 config files in /usr/kde/3.2/share/config need updating.
 * Type emerge --help config to learn how to update config files.

象这样的信息相信大家都见过了吧。要update这些config文件,可以用etc-update,不过我这儿想介绍一个类似的工具,dispatch-conf。这是我的配置档/etc/dispatch-conf.conf:


代码:
#
# dispatch-conf.conf
#

# Directory to archive replaced configs
archive-dir=/etc/config-archive

# Use rcs for storing files in the archive directory?
# (yes or no)
use-rcs=yes

# Diff for display
diff="diff -Nau %s %s"

# Pager for diff display
pager="less --no-init --QUIT-AT-EOF"

# Automerge files comprising only CVS interpolations (e.g. Header or Id)
# (yes or no)
replace-cvs=yes

# Automerge files comprising only whitespace and/or comments
# (yes or no)
replace-wscomments=yes

# Automerge files that the user hasn't modified
# (yes or no)
replace-unmodified=yes

如果要使用rcs,首先要:


# emerge rcs


当然还要:


# mkdir /etc/config-archive


用dispatch-conf来更新config文件很简单,运行:


# dispatch-conf


首先dispatch-conf会将要update的config文件在/etc/config-archive里做个备份,然后会一个个显示需要处理 的 文件。你会看到文件里(look-merge)有些行前面有+或-的符号(diff的显示),这代表automerge会将这些行加入或删减 (按空 格键翻页,如果文件太长,按‘q’退出),你会看到类似这样的信息:


代码:
>> (1 of 33) -- /etc/DIR_COLORS
>> q quit, h help, n next, e edit-new, z zap-new, u use-new
   m merge, t toggle-merge, l look-merge:

如果按m进行merge,你会看到/etc/DIR_COLORS和/etc/._cfg0000_DIR_COLORS并列出现,旧的在左边,新的在右边。


然后可以按以下的命令进行merge:


代码:
ed:     Edit then use both versions, each decorated with a header.
eb:     Edit then use both versions.
el:     Edit then use the left version.
er:     Edit then use the right version.
e:      Edit a new version.
l:      Use the left version.
r:      Use the right version.
s:      Silently include common lines.
v:      Verbosely include common lines.
q:      Quit.

完成后,会显示新的将会变更的内容;按’q‘退出,然后按e(edit-new)做最后的编辑。接着就可以按’u‘启用新的文件了(/etc/._cfg0000_DIR_COLORS当然会给删掉了)。


以上是人手作merge的一个例子,实际上很多文件都可以直接按’u‘采用新版,尤其是/etc/init.d/里的那些脚本及一些你从不会去改的文件(以上的/etc/DIR_COLORS便是一例

)。Gentoo特有的东西,象make.conf这样的,最好是人手merge一下;象fstab这样的标准linux配置文件则可以直接zap-new,即删了._cfg0000_fstab然后继续。



PS 以上有些步骤与etc-update雷同,至于用哪个工具,使用者自己决定吧。

B、B-、B+、B*-Tree

B树

       即二叉搜索树:
       1.所有非叶子结点至多拥有两个儿子(Left和Right);
       2.所有结点存储一个关键字;
       3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;
       如:
       
       B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;
       如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;
       如:
      
    但B树在经过多次插入与删除后,有可能导致不同的结构:

   右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;      
       实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;
 
B-树
       是一种多路搜索树(并不是二叉的):
       1.定义任意非叶子结点最多只有M个儿子;且M>2;
       2.根结点的儿子数为[2, M];
       3.除根结点以外的非叶子结点的儿子数为[M/2, M];
       4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
       5.非叶子结点的关键字个数=指向儿子的指针个数-1;
       6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
       7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
       8.所有叶子结点位于同一层;
       如:(M=3)
       B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;
B-树的特性:
       1.关键字集合分布在整颗树中;
       2.任何一个关键字出现且只出现在一个结点中;
       3.搜索有可能在非叶子结点结束;
       4.其搜索性能等价于在关键字全集内做一次二分查找;
       5.自动层次控制;
       由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少利用率,其最底搜索性能为:
    
       其中,M为设定的非叶子结点最多子树个数,N为关键字总数;
       所以B-树的性能总是等价于二分查找(与M值无关),也就没有B树平衡的问题;
       由于M/2的限制,在插入结点时,如果结点已满,需要将结点分裂为两个各占M/2的结点;删除结点时,需将两个不足M/2的兄弟结点合并;
 
B+树
       B+树是B-树的变体,也是一种多路搜索树:
       1.其定义基本与B-树同,除了:
       2.非叶子结点的子树指针与关键字个数相同;
       3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
       5.为所有叶子结点增加一个链指针;
       6.所有关键字都在叶子结点出现;
       如:(M=3)
   B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;
       B+的特性:
       1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
       2.不可能在非叶子结点命中;
       3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
       4.更适合文件索引系统;
 
B*树
       是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;
   B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2);
       B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;
       B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;
       所以,B*树分配新结点的概率比B+树要低,空间使用率更高;
 
各类Tree总结:      
       B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
       B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
       B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
       B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;

find

Find命令是一个非常有效的工具,它可以遍历当前目录甚至于整个文件系统来查找某些文件或目录。
Find命令的一般形式为:
find pathname -options [-print -exec -ok]
让我们来看看该命令的参数:

 

参数 描述
pathname find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。 
-print find命令将匹配的文件输出到标准输出。
-exec find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为command {} \;,注意{ }和\;之间的空格。
-ok 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

options最常见选项:

option 描述
-name 按照文件名查找文件
-perm 按照文件权限来查找文件
-user 按照文件属主来查找文件
-group 按照文件所属的组来查找文件
-mtime -n +n 按照文件的更改时间来查找文件,-n表示文件更改时间距现在n天以内,+n 表示文件更改时间距现在n天以前。Find命令还有-atime和-ctime选项,但它们都和-mtime选项相似,所以我们在这里只介绍-mtime选项
-type 查找某一类型的文件,比如:b - 块设备文件;d - 目录;c - 字符设备文件;p - 管道文件;l - 符号链接文件;f - 普通文件
-size n[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计

以下是一些常见实例:

命令 描述
find . -name "*.txt" -print 在当前目录及子目录中查找所有的'*.txt'文件
find . -name "[A-Z]*" -print 当前目录及子目录中查找文件名以一个大写字母开头的文件
find /etc -name "host*" -print 在/etc目录中查找文件名以host开头的文件
find . -name "[a-z][a-z][0--9][0--9].txt" -print 在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是*.txt的文件
find . -size +1000000c -print 在当前目录下查找文件长度大于1 M字节的文件

 

使用exec或ok来执行shell命令
当匹配到一些文件以后,可能希望对其进行某些操作,这时就可以使用-exec选项。一旦find命令匹配到了相应的文件,就可以用-exec选项中的命令对其进行操作(在有些操作系统中只允许-exec选项执行诸如ls或ls -l这样的命令)。大多数用户使用这一选项是为了查找旧文件并删除它们。这里我强烈地建议你在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。
exec选项后面跟随着所要执行的命令,然后是一对儿{ },一个空格和一个\,最后是一个分号

 

用xargs代替exec/ok
在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。不幸的是,有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是"参数列太长"或"参数列溢出"。这就是xargs命令的用处所在,特别是与find命令一起使用。find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

 

以下是一些exec/ok/xargs使用的常见实例:

命令 描述
find logs -type f -mtime +5 -exec rm {} \; 在/logs目录中查找更改时间在5日以前的文件并删除它们
find / -type f -size 0 -exec ls -l {} \; 系统中所有文件长度为0的普通文件,并列出它们的完整路径
find /var/logs -type f -mtime +7 -exec rm {} \; 查找/var/logs目录中更改时间在7日以前的普通文件,并删除它们
find . -name "core" -print | xargs echo "" >/tmp/core.log 在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中
find / -type f -print | xargs grep "device" 用grep命令在所有的普通文件中搜索device这个词

记住,在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心!

重定向操作符

经常看到这样的语句:mysh > mylog.txt 2>&1是什么意思?

 

重定向操作符可以用来将命令输入和输出数据流从默认位置重定向到其他位置,其输入或输出数据流的位置称为句柄;常见的句柄有三种,当然句柄可以自行扩展,一般的OS都提供类似的功能:

 

句柄 句柄代号 句柄描述
STDIN 0 键盘输入
STDOUT 1 输出信息到提示符窗口
STDERR 2 输出错误信息到提示符窗口

默认的 < 重定向输入操作符是 0,而默认的 > 重定向输出操作符是 1。键入 < 或 > 操作符之后,必须指定数据的读写位置,可以是文件名或其他现有的句柄。
要指定重定向到现有句柄,请使用与 & 字符,后面接要重定向的句柄号(即 &句柄号)。
例如,下面的命令可以将句柄 2(即 STDERR)重定向到句柄 1(即 STDOUT):2>&1
下表列出了可用于重定向输入和输出数据流的操作符:

 

重定向操作符 功能描述
> 将命令输出写入文件或设备,而不是命令提示符或句柄
< 从文件而不是从键盘或句柄读入命令输入
>> 将命令输出添加到文件末尾而不删除文件中已有的信息
>& 将一个句柄的输出写入到另一个句柄的输入中
<& 从一个句柄读取输入并将其写入到另一个句柄输出中
| 从一个命令中读取输出并将其写入另一个命令的输入中;也称为管道操作符

现在我们回过头来看看上面的那条语句mysh > mylog.txt 2>&1就可明白:

> mylog.txt意思是将标准输出重定向到mylog.txt,等价于mysh 1> mylog.txt;

2 >& 1 意思是将错误输出重定向到句柄1标准输出;综合起来就是mysh命令执行过程中产生的标准输出和错误输出都会被重定向到mylog.txt中;

重定向的功能十分强大,有兴趣的可以去尝试各种不同的组合,看看前后位置变下会有什么结果?

某些时候我们可能并不希望记录什么标准输出或者是错误输出,那可以用mysh >null 2>null或者mysh >/dev/null 2>/dev/null;

crontab

crontab 指定在固定时间或固定间隔执行特定的脚本;crontab的常用参数有如下3个:

-e :执行文字编辑器来设定日程表,一般默认的编辑器是VI;

-r :删除目前所有的日程表;

-l :列出目前所有的日程表;

设置日程表时,需要有固定的格式,共6部分,各部分间用空格间隔;其中第6个部分是要执行的命令,前5个部分是设置执行时间或者时间间隔的,具体取值范围和意义如下:

分钟【0-59】 小时【0-23】 日【1-31】 月份【1-12】 星期【0-6】

在设置的时候可以每项有4种指定方式,如下:

* :表示每 分钟/.../星期 都需要执行;

a-b :表示从第 a 分钟/.../星期 到第 b 分钟/.../星期 这段期间都需要执行;

*/n :表示每 n个 分钟/.../星期 时间间隔执行一次;

a,b,c :表示第 a,b,c 分钟/.../星期 时需要执行,也即指定多个具体时间点;

举个例子来说,比如要指定每日早上7点执行脚本mysh的crontab设置如下:

0 7 * * * /home/admin/mysh >/home/admin/mylog.txt 2>&1

冯诺依曼结构和哈佛结构

哈佛结构

    数字信号处理一般需要较大的运算量和较高的运算速度,为了提高数据吞吐量,在数字信号处理器中大多采用哈佛结构,如下图所示

图   哈佛结构

与冯.诺曼结构处理器比较,哈佛结构处理器有两个明显的特点:

  • 使用两个独立的存储器模块,分别存储指令和数据,每个存储模块都不允许指令和数据并存;

  • 使用独立的两条总线,分别作为CPU与每个存储器之间的专用通信路径,而这两条总线之间毫无关联。

     后来,又提出了改进的哈佛结构,如下图所示

图    改进型哈佛结构

其结构特点为:

  • 使用两个独立的存储器模块,分别存储指令和数据,每个存储模块都不允许指令和数据并存,以便实现并行处理;

  • 具有一条独立的地址总线和一条独立的数据总线,利用公用地址总线访问两个存储模块(程序存储模块和数据存储模块),公用数据总线则被用来完成程序存储模块或数据存储模块与CPU之间的数据传输;

  • 两条总线由程序存储器和数据存储器分时共用。

    在典型情况下,完成一条指令需要3个步骤,即:取指令、指令译码和执行指令。从指令流的定时关系也可看出冯.诺曼结构与哈佛结构处理方式的差别。举一个最简单的对存储器进行读写操作的指令,如下图所示,指令1至指令3均为存、取数指令,对冯.诺曼结构处理器,由于取指令和存取数据要从同一个存储空间存取,经由同一总线传输,因而它们无法重叠执行,只有一个完成后再进行下一个。

图  .诺曼结构处理器指令流的定时关系示意图

 

     如果采用哈佛结构处理以上同样的3条存取数指令,如下图所示,由于取指令和存取数据分别经由不同的存储空间和不同的总线,使得各条指令可以重叠执行,这样,也就克服了数据流传输的瓶颈,提高了运算速度。

 

    哈佛结构强调了总的系统速度以及通讯和处理器配置方面的灵活性。

 

 

 

 

 

 

 

图   哈佛结构处理器指令流的定时关系示意图

========================================================================

冯.诺曼结构

    1945年,冯.诺曼首先提出了“存储程序”的概念和二进制原理,后来,人们把利用这种概念和原理设计的电子计算机系统统称为“.诺曼型结构”计算机。冯.诺曼结构的处理器使用同一个存储器,经由同一个总线传输,如下图所示:

图   冯.诺曼结构

    .诺曼结构处理器具有以下几个特点:

  • 必须有一个存储器;

  • 必须有一个控制器;

  • 必须有一个运算器,用于完成算术运算和逻辑运算;

  • 必须有输入和输出设备,用于进行人机通信。

    .诺曼的主要贡献就是提出并实现了“存储程序”的概念。由于指令和数据都是二进制码,指令和操作数的地址又密切相关,因此,当初选择这种结构是自然的。但是,这种指令和数据共享同一总线的结构,使得信息流的传输成为限制计算机性能的瓶颈,影响了数据处理速度的提高。   

     在典型情况下,完成一条指令需要3个步骤,即:取指令、指令译码和执行指令。从指令流的定时关系也可看出冯.诺曼结构与哈佛结构处理方式的差别。举一个最简单的对存储器进行读写操作的指令,如下图所示,指令1至指令3均为存、取数指令,对冯.诺曼结构处理器,由于取指令和存取数据要从同一个存储空间存取,经由同一总线传输,因而它们无法重叠执行,只有一个完成后再进行下一个。

图  .诺曼结构处理器指令流的定时关系示意图

shell中的printf

可进行进制转换:

printf "%d\n" 0x7fec

printf "%x\n" 537993216
 

perl -e 'print localtime(1111986). "\n";'
perl -e 'print localtime(672274793). "\n";'

perl -e 'print localtime(29091986). "\n";'

unsigned int 与 int 之和

面试题:

unsigned int a = 6;

int b = -20;

int c;

(a+b>6)?(c=1):(c=0)

问:

c=?

 

看下面这段:

K & R A.6.5
Arithmetic Conversions
First, if either operand is long double, the other is converted to long double.
Otherwise, if either operand is double, the other is converted to double.
Otherwise, if either operand is float, the other is converted to float.
Otherwise, the integral promotions are performed on both operands; then, if either operand is unsigned long int, the other is converted to unsigned long int.
Otherwise, if one operand is long int and the other is unsigned int, the effect depends on whether a long int can represent all values of an unsigned int; if so, the unsigned int operand is converted to long int; if not, both are converted to unsigned long int.
Otherwise, if one operand is long int, the other is converted to long int.
Otherwise, if either operand is unsigned int, the other is converted to unsigned int.
Otherwise, both operands have type int.

简单翻译如下:
如果任一个操作数是long double, 则另一个要转换为long double
如果任一个操作数是double, 则另一个要转换为double
如果任一个操作数是float, 则另一个要转换为float
此外整数运算符升级对两个操作数都有影响;
如果任一个操作数是unsigned long int, 则另一个要转换为unsigned long int
如果一个操作数是long int, 另一个是unsigned int, 如果long int可以表示结果,则unsigned int要转换为long int;
否则两个都转换为unsigned long int
如果任一个操作数是long int, 则另一个要转换为long int
如果任一个操作数是unsigned int, 则另一个要转换为unsigned int
除此之外,两个操作数都应是int

 

倒数第二句是解本题的关键:

如果任一个操作数是unsigned int, 则另一个要转换为unsigned int

首先将b=-20用补码表示:

20的二进制:

0000 0000 0001 0100

取反:

1111 1111 1110 1011

再加1:

1111 1111 1110 1100

把第一个代表负号的1去掉,

0111 1111 1110 1100

把上面作为unsigned int 是十进制32748

财(a+b)肯定大于6,

则c=1