Linux进程的层次关系 (Linux/Unix)
发布于 2009-02-16 19:40 阅读:39734 评论:0 标签: Linux 进程

    前段时间在看清华大学出版社出版的《Linux教程》(05年6月第一版)。在248页第十三章《进程》有一节是简述Linux进程的层次关系的,把操作系统自启动后都做了什么,说得比较清晰,看过后受益匪浅。

    就是喜欢看这种能把整个框架说得比较清楚的文章!特抄来以共享:

    当打开Linux系统,LILO(LInux LOader)找到Linux内核把它加载到内存。它初始化各种硬件,包括磁盘控制器。然后转到保护模式,加载操作系统,执行初始化各种内核数据结构的代码,例如inode和文件表。此进程的PID为0。它启动初试进程(init进程,PID为1)完成引导过程的其余工作。init进程启动守护进程kflushd、kupdate、kpiod和kswapd,其PID分别为2、3、4、5。Init进程然后初始化文件系统,安装根文件系统。接下来试着执行/sbin/init程序,在每一个激活的终端上执行minegetty进程(经常被称为getty进程)。getty进程设置终端属性,如波特率,这些属性在/etc/termcap文件中都有定义。它显示login:提示符,等待用户登录。

    在login:提示符下,输入登录名并按回车键,getty进程产生一个子进程。它转变为以登录名为参数的登录进程。登录进程提示输入密码,并检查输入名和密码的有效性。如果两者均正确,登录进程产生一个子进程,它将转变为登录shell。如果登录进程没有在/etc/passwd文件中找到登录名或者输入的密码与/etc/passwd文件中(或者/etc/shadow文件)存放的密码不匹配,他将显示错误提示信息然后终止。控制权又回到getty进程,重新显示login:提示符。一旦进入登录shell,就可以完成自己的工作,还可以按<ctrl-D>键终止当前shell。如果这样做了,shell进程会终止,控制权又回到getty进程,再次显示login:提示符,又开始循环。

    就是说,当登录到Linux系统,系统产生第一个进程,称为登录进程,它又创建登录shell。登录shell为所输入的命令创建进程,用以解释/执行命令。

    两个Linux进程贯穿系统生命周期:swapper和init进程。监视终端行的getty进程,只要终端与系统关联上就会一直存在。登录进程和登录shell进程只有在登录时才存在。所有其它进程生存期较短,只在命令或者程序执行时短暂存在。

    ps -ef 命令或者pstree命令可以用图的形式显示当前系统中执行进程的进程树,勾勒出进程间的父子关系。pstree命令显示的图比ps -ef命令更简洁。pstree显示的结果,前有“+”的是当前的后台进程,而前面的有“-”的是后续后台进程。pstree命令使用-h参数,输出用粗体(加亮)显示当前进程。使用“-a”选项,pstree显示带参数的命令。如“pstree 402 -a”可以显示PID为402的进程的那个的层次关系。

    Bash shell可以使用ulimit显示用户可以同时执行的最大进程个数。TC shell下为limit。两个命令都可以用来显示硬件和操作系统资源的使用限制。

展开全文  
收起全文  
与君共勉:有想法 就行动 (随便说说)
发布于 2009-02-13 18:56 阅读:49360 评论:1 标签: 生活 行动

    与君共勉:有想法 就行动。

    蜀之鄙有二僧,其一贫,其一富。贫者语于富者曰:“吾欲之南海,何如?”。富者曰:“子何恃而往?”曰:“吾一瓶一钵足矣”。富者曰:“吾数年来欲买舟而下,犹未­能也。子何恃而往?”。越明年,贫者自南海还,以告富者。富者有惭色。

展开全文  
收起全文  
查看、分析memcached使用状态 (Linux/Unix)
发布于 2009-02-12 22:44 阅读:26491 评论:0 标签: memcached stats 缓存

    访问量上升,数据库压力大,怎么办?好办法是在中间挡一层缓存!这个缓存要求高效,不能比数据库慢,否则服务质量受影响;如果能把数据用hash打散存储到硬盘,也是可以的,不过在内存越来越便宜的今天,还是使用内存吧!

    mysql也有自己的缓存,也是存储在内存的,但是有一个说法是:

以下是引用片段:

只能有一个实例
意味着你能存储内容的上限就是你服务器的可用内存,一台服务器能有多少内存?你又能存多少呢?

只要有写操作,mysql的query cache就失效
只要数据库内容稍有改变,那怕改变的是其他行,mysql的query cache也会失效

    再说,如果mysql都抗不住了,怎么还能指望它提供的缓存呢?

    所以我可以使用memcached了!他的好处和如何用可以参考:

以下是引用片段:

1:《Memcache和mysql交互流程操作原理

2:《让memcached和mysql更好的工作

    开发时面对需求是个麻烦事,更漫长而闹心的是维护,所以我更关心的是memcached运行中的情况。还好的是,memcached的作者给我们提供查看运行情况的命令。主要是“stats”,使用方法为 “telnet ip 端口号”,登录后使用“stats”命令。

    然后你可以看见很多内容,具体可以参考:《memcacche stats

以下是引用片段:

pid = process id
uptime = number of seconds since the process was started
time = current time
version = memcached version
rusage_user = seconds the cpu has devoted to the process as the user
rusage_system = seconds the cpu has devoted to the process as the system
curr_items = total number of items currently in memcache
total_items = total number of items that have passed through the cache
bytes = total number of bytes currently in use by curr_items
curr_connections = total number of open connections to memcached
connection_structures = ???
cmd_get = total GET commands issued to the server
cmd_set = total SET commands issued to the server
get_hits = total number of times a GET command was able to retrieve and
return data
get_misses = total number of times a GET command was unable to retrieve and
return data
bytes_read = total number of bytes input into the server
bytes_written = total number of bytes written by the server
limit_maxbytes = total storage bytes available to the server.

    着重说一下几个对观测很有用的项。

    limit_maxbytes、bytes

    memcached在存储的时候是可以设置失效时间的,但如果存储已经满了,那旧数据即使没有到过期时间,也会被移除。所以需要观察memcached存储是否已经满了,同时这对扩容也是有意义的参考。limit_maxbytes即总的存储大小,而bytes就是已经使用的大小,从这两个数据就可以看出在memcached启动时,我们为它分配的内存是否足够使用。

    cmd_get、cmd_set

    memcached启动后,我们对它一共做了多少次读取操作呢?从这两个参数可以观察出来。

    get_hits、get_misses

    使用memcached后,我们需要评估我们使用的策略是否合理。不能够使用中间缓存后,后端的数据库还是有较大的访问量,这样的话中间缓存就变得没有意义了。get_hits表示命中了多少次读取,即来memcached取到了多少有效数据;get_misses表示没有命中的次数,即此次来取数据的时候,memcached并没有你所查询的数据。如果没有清零统计数据的话,cmd_get = get_hits + get_misses。

    memcached 的状态查询还有其它的命令,可以参考:《Memcached的stats命令

    如下:

stats reset
清空统计数据

stats malloc
显示内存分配数据

stats maps
这个不太确定,看源代码是把/proc/self/maps的数据显示出来。

stats cachedump slab_id limit_num
显示某个slab中的前limit_num个key列表,显示格式如下
ITEM key_name [ value_length b; expire_time|access_time s]
其中,memcached 1.2.2及以前版本显示的是  访问时间(timestamp)
1.2.4以上版本,包括1.2.4显示 过期时间(timestamp)
如果是永不过期的key,expire_time会显示为服务器启动的时间

stats cachedump 7 2
ITEM copy_test1 [250 b; 1207795754 s]
ITEM copy_test [248 b; 1207793649 s]

stats slabs
显示各个slab的信息,包括chunk的大小、数目、使用情况等

stats items
显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)

stats detail [on|off|dump]
设置或者显示详细操作记录

参数为on,打开详细操作记录
参数为off,关闭详细操作记录
参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)

stats detail dump
PREFIX copy_test2 get 1 hit 1 set 0 del 0
PREFIX copy_test1 get 1 hit 1 set 0 del 0
PREFIX cpy get 1 hit 0 set 0 del 0

展开全文  
收起全文  
实时观察Apache访问情况的工具Apachetop (Linux/Unix)
发布于 2009-02-11 20:39 阅读:31670 评论:1 标签: apachetop log

    Linux服务器的负载、进程等信息可以通过top命令查看。而Apache的运转如何实时的观察呢?“tail -f”log文件?这是个好方法,但是太累了!

    所以,感谢Chris Elsworth为我们提供了类似top命令的apachetop命令!官网地址:http://www.webta.org/projects/apachetop/

    apachetop可以查看最近一段时间和自命令执行以来的apache访问情况,信息包括被访问的文件、次数、流量大小。

    命令安装、使用可以查看官网提供的说明:http://www.webta.org/projects/apachetop/browser/README,或者查看一个中文的解释:《实时跟踪log变化的工具Apachetop》。

    在此我对命令显示信息和一些好用的参数做一下说明。

    先看命令显示:

以下是引用片段:

last hit: 11:19:12         atop runtime:  0 days, 07:12:27             11:19:13
All:      1553476 reqs (  59.9/sec)       3566.4M (  140.7K/sec)    2407.3B/req
2xx: 1458916 (93.9%) 3xx:   93768 ( 6.0%) 4xx:   787 ( 0.1%) 5xx:     5 ( 0.0%)
R ( 30s):    1692 reqs (  56.4/sec)       4342.8K (  144.8K/sec)    2628.3B/req
2xx:    1606 (94.9%) 3xx:      85 ( 5.0%) 4xx:     1 ( 0.1%) 5xx:     0 ( 0.0%)

 REQS REQ/S    KB KB/S URL
  916 30.53  1202 40.1*/api/chk.php
   71  2.37 433.7 14.5 /login.php
   50  1.67  44.6  1.5 /css/css.css
   39  1.50 506.4 19.5 /js/js.js

    第一行的“last hit: 11:19:12”和“11:19:13”分别显示此次显示时的最后观察时间,和现在的时间。不过我对这个时间很不理解,因为这个世界和系统的时间是不一致的。不知道是我理解有误还是怎么回事,忘有知情的朋友留言告诉我。

    第一行中间的部分表示这个命令运行了多长时间。

    第二、三行显示的是自命令执行以来观察到的所有数据汇总。第四、五行显示的是近30表的数据汇总。前一行表示:总请求数、每秒处理的请求数、总的数据传输量、每个请求的数据传输量。后一行显示http响应类型、此类型的总数、每秒的此类型的响应数。这个还是很好理解的。

    再往后的数据则从访问量大小排列出了是哪些程序在被访问。格式照上也很好理解。

    有几个很有用的参数值的学习一下。

    -f:这个参数指定了apachetop命令观察的对象。并不是每个人的apache的日志都在默认的位置,甚至你为了统计的方便,使用多个日志文件来区分不同的端口(80、443)、正确和错误的访问日志、等等。这个时候可以使用这个参数来指定log文件。尤其有用的是,你可能需要同时查看多个log的情况,这时你可以多次使用-f参数来制定,如: apachetop -f file1 -f file2。

    -d:默认情况下,显示界面每5秒刷新一次,如果你觉得刷新频率不爽,你可以使用这个参数来做改变。

    -T:上面的例子中,我们在最后面看到的是最近30秒的情况。如果你觉得密度不够,可以使用这个参数来做改变。

    -H:还是上面的例子,可以看到最近30秒的请求总数是:1606+85+1+0=1692次。如果你想让每请求N次刷新一次界面怎么办?哈,就是使用这个命令了!

    注意:-T和-H参数是不能同时使用的,否则会提示你:“-T and -H are mutually exclusive. Specify only one.”

    -q:有一些程序,在使用的时候是可以带参数的,即get方式。如果你想看看都是些什么参数,就可以使用这个命令了!

    看完以后,不要忘了,如果你知道第一行的“last hit: 11:19:12”和“11:19:13”分别显示的是什么,别忘了告诉我。。。。。

展开全文  
收起全文  
Linux下查看文件和文件夹大小的df和du命令 (Linux/Unix)
发布于 2009-02-09 18:07 阅读:211630 评论:0 标签: df du 文件大小

    当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择。

    df可以查看一级文件夹大小、使用比例、档案系统及其挂入点,但对文件却无能为力。
    du可以查看文件及文件夹的大小。

    两者配合使用,非常有效。比如用df查看哪个一级目录过大,然后用df查看文件夹或文件的大小,如此便可迅速确定症结。

    下面分别简要介绍

    df命令可以显示目前所有文件系统的可用空间及使用情形,请看下列这个例子:

以下是代码片段:

[yayug@yayu ~]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             3.9G  300M  3.4G   8% /
/dev/sda7             100G  188M   95G   1% /data0
/dev/sdb1             133G   80G   47G  64% /data1
/dev/sda6             7.8G  218M  7.2G   3% /var
/dev/sda5             7.8G  166M  7.2G   3% /tmp
/dev/sda3             9.7G  2.5G  6.8G  27% /usr
tmpfs                 2.0G     0  2.0G   0% /dev/shm

    参数 -h 表示使用「Human-readable」的输出,也就是在档案系统大小使用 GB、MB 等易读的格式。

    上面的命令输出的第一个字段(Filesystem)及最后一个字段(Mounted on)分别是档案系统及其挂入点。我们可以看到 /dev/sda1 这个分割区被挂在根目录下。

    接下来的四个字段 Size、Used、Avail、及 Use% 分别是该分割区的容量、已使用的大小、剩下的大小、及使用的百分比。 FreeBSD下,当硬盘容量已满时,您可能会看到已使用的百分比超过 100%,因为 FreeBSD 会留一些空间给 root,让 root 在档案系统满时,还是可以写东西到该档案系统中,以进行管理。

    du:查询文件或文件夹的磁盘使用空间

    如果当前目录下文件和文件夹很多,使用不带参数du的命令,可以循环列出所有文件和文件夹所使用的空间。这对查看究竟是那个地方过大是不利的,所以得指定深入目录的层数,参数:--max-depth=,这是个极为有用的参数!如下,注意使用“*”,可以得到文件的使用空间大小.

    提醒:一向命令比linux复杂的FreeBSD,它的du命令指定深入目录的层数却是比linux简化,为 -d。

以下是代码片段:

[root@bsso yayu]# du -h --max-depth=1 work/testing
27M     work/testing/logs
35M     work/testing

[root@bsso yayu]# du -h --max-depth=1 work/testing/*
8.0K    work/testing/func.php
27M     work/testing/logs
8.1M    work/testing/nohup.out
8.0K    work/testing/testing_c.php
12K     work/testing/testing_func_reg.php
8.0K    work/testing/testing_get.php
8.0K    work/testing/testing_g.php
8.0K    work/testing/var.php

[root@bsso yayu]# du -h --max-depth=1 work/testing/logs/
27M     work/testing/logs/

[root@bsso yayu]# du -h --max-depth=1 work/testing/logs/*
24K     work/testing/logs/errdate.log_show.log
8.0K    work/testing/logs/pertime_show.log
27M     work/testing/logs/show.log

    值得注意的是,看见一个针对du和df命令异同的文章:《du df 差异导致文件系统误报解决》。

    du 统计文件大小相加
    df  统计数据块使用情况

    如果有一个进程在打开一个大文件的时候,这个大文件直接被rm 或者mv掉,则du会更新统计数值,df不会更新统计数值,还是认为空间没有释放。直到这个打开大文件的进程被Kill掉。

    如此一来在定期删除 /var/spool/clientmqueue下面的文件时,如果没有杀掉其进程,那么空间一直没有释放。

    使用下面的命令杀掉进程之后,系统恢复。
    fuser -u /var/spool/clientmqueue

展开全文  
收起全文  
不是每个人都和你想的一样 (随便说说)
发布于 2009-02-09 15:57 阅读:43055 评论:0 标签:

    不是每个人都和你想的一样,从上到下皆是。

    大的方面说。

    2008年2月5日晚,央视一套播出2008年《感动中国》人物的颁奖仪式,颁奖仪式打破常规(其实学老外:在这里),将年度特别奖授予了全体中国人(在这里)。白岩松的颁奖说词如下(这里有):

以下是引用片段:

我们每一个人都有权接过这个奖杯,因为我们都是获奖者。然而,我们每一个人都没有理由,让这个奖杯,在我们的身边停留得太久,因为我们只是十三亿分之一。历史会认同,2008年这份特殊的奖励,此刻我们看到这个奖杯,真的觉得它意味深长,这是因为它是在孩子手里。

    可是,很多有独立思考的人并不这么想。

    著名律师刘晓原在博文《拒领“2008感动中国”年度特别奖》里以一个中国普通公民身份表达自己的声音:

以下是引用片段:

  我是一个无贡献者,也是一个守法公民。与有功绩者一起获奖,我感到受之有愧;与腐败分子一同获奖,我感到无地自容。作为一个有自知之明的公民,我在此郑重地声明,拒绝领取中央电视台颁发的“感动中国”年度特别奖。基于奖项是授予全体中国人的,我拒绝领取其中的十三亿分之一“份额”。
  我只是一名普通公民,做不了感动国家的事情,敬请中央电视台予以谅解!

                    北京市忆通律师事务所刘晓原律师

    童话大王郑渊洁似乎也赞同这个观点。当然,搞文学的比较含蓄,于是借咬文嚼字的提出了抗议:(“抗议”是我的臆断)(原文在这里

以下是引用片段:

“中国人”的概念应该是所有持有中华人民共和国护照(包括台湾护照)的人。“全体中国人”当选2008年感动中国年度特别奖,自然也必须包括陈水扁和两岸所有东窗事发和尚未穿帮的贪官。

........................

    我国今年的《国防白皮书》就因为使用错了一个标点符号,引起外国误解。那句话是这样的:“中国主张所有核武器国家明确承诺全面、彻底销毁核武器,并承诺停止研发新型核武器,降低核武器在国家安全政策中的作用。”结果外国各大媒体都使用通栏大标题争先恐后报道:中国承诺停止研发新型核武器!

........................

    作为中国人,说好中国话写好中国文很重要。语言是民族的立身之本,秦始皇最伟大的功绩是在中国统一了文字。为什么中国到现在还没分裂?统一的文字是头功。全体中国人在没有充分到位掌握母语之前趋之若鹜本末倒置学外文,对民族不是幸事。无源之水无本之木多了,民族就有成为海市蜃楼的风险。

    如果你不了解“神奇的国度”的含义,你可能理解不了他们为啥要挑刺,“给脸不要脸”。不过你可以看看这个《不是我说的》来理解一下,然后看看《专家又变卦了……》来加深一下理解。

    小的方面说。

    上网的用户都是怎么想的呢?许晓辉说“你和用户其实想得不一样・白天不懂夜的黑”:

以下是引用片段:

 用户不关心流氓。春节回家用大姐的电脑,发现首页是1616.net导航站;刚上一年级的外甥女很流利的打开2144.cn玩flash小游戏;而地址栏搜索是QQ的天下。就在我们高谈阔论流氓推广的时候,广大网民已经在大大小小的网站上乐不思蜀了。对于像大姐家小孩一样的初级网民而言,他们根本就不关心什么流氓推广,只要产品好用就行,即使不好用他们也不知道如何卸载。这也就是网址导航站、网络实名等能够迅速普及的原因。(诸如1616、2144这类网站,你从网上很难找到他们的作者是谁,但却真真实实的安装到了无数电脑之中,并为幕后作者提供着源源不断的广告收入)

    可是我回家在网吧上网看见的不是这样的,用户貌似很明确自己的目的。网吧的系统一般请一个公司来装,然后这个公司就把这个机器的IE主页设置为自己做的。比如我来的这个网吧,他弄的主页类似百度,正中是一个百度的搜索框,四周再整点导航,百度的搜索框很很醒目。然而,我看见左边座位上先后两个人都是打开默认主页后,无视醒目的百度搜索框,而是很熟练的在地址栏里面敲入“www.baidu.com”。动作之熟练,令我汗颜:)

    不过,我和许晓辉看见的用户数很少,不足以作为数据说明。或许,这也就是我一直所想的,做网站不一定要功能全面,能够满足一部分的用户的需求,就已经足够了。

    一直不敢多议他人,皆源于此。

展开全文  
收起全文  
小糊涂了一把,哈哈 (随便说说)
发布于 2009-01-19 19:30 阅读:9644 评论:0 标签: 糊涂

       以前遇到过这种事情,今天又糊涂了一把。

以下是代码片段:

[root@login yayu]# ls -la
.............................
-rw-r--r--  1 root      root        49 Jan 19 19:20 loglog
[root@login yayu]#
[root@login yayu]# cat loglog
Directory "/data2/logs/error" is not exists
[root@login yayu]#
[root@login yayu]# ls -l /data2/logs/error
ls: /data2/logs/error: No such file or directory

展开全文  
收起全文  
PHP的变量也不是随意能转化的及bash的算术运算 (PHP心得)
发布于 2008-12-30 20:47 阅读:11719 评论:0 标签: array bash scalar

      一直以为PHP的变量是很灵活的,类型想怎么变换就怎么变换。

      但实际上并不是这样,当一个变量被赋值为数字时,是变换不了数组的,比如:

以下是代码片段:

[root@localhost shengting]# cat test.php
<?php
$a = 454;
$b = 6;
$a['gfgo'] = $b;

var_dump($a);
?>

[root@localhost shengting]# php test.php
PHP Warning:  Cannot use a scalar value as an array in /usr/home/shengting/test.php on line 4

Warning: Cannot use a scalar value as an array in /usr/home/shengting/test.php on line 4
int(454)

      从var_dump的结果看,不仅有Warning级的错误,赋值也没有成功。而,如果变量一开始是字符串的话,就没这回事情了:

以下是引用片段:

[root@localhost shengting]# cat test.php
<?php
$a = `454`;
$b = 6;
$a['gfgo'] = $b;

var_dump($a);
?>
[root@localhost shengting]# php test.php
sh: 454: command not found
array(1) {
  ["gfgo"]=>
  int(6)
}

      可以看出,赋值是成功的。

      应该,这个是和存储的类型是有联系的。同样,在Shell的Bash中,所有的变量的值都是以字符串方式存储的。尽管这个特性使得bash的数据处理起来很容易,但是也使得数字运算比较困难。原因就是数字也是以字符串的形式存储的,

      在Bash中,如果要对数字进行算术运算和逻辑操作,必须先转化为整数(可视为中间值),得到运算结果后再转化为字符串,以便正确的保存在Bash变量中。

      Bash提供了三种方式的数字数据进行算术变量:

以下是引用片段:

1:使用let命令。
2:使用shell扩展 $((expression))
3:使用expr命令

      具体用法就不说了,哈哈。偶比较喜欢使用第二种。

展开全文  
收起全文  
做个有意思的小网站,看着它长大 (随便说说)
发布于 2008-12-29 21:16 阅读:145180 评论:1 标签: blogread 博客导航 小钱包

    今天通过Google Reader看见一米六二的北漂生活里的一个文章,说他“一直梦想着做一个NB的不行帅到让人拉一裤子的小东西”,看完文章,突然觉得很感动,这不也是我想做的么?!

     他弄的是一个叫做“小钱包”的网站,是“一个好玩的、简单的不能再简单了的在线记账应用”的网站。应用的确是很简单,可是当你自己根据兴趣去做一件事情的时候,难道不觉得很有成就感么?这个也是我从事互联网的引子,可是这种感觉随着工作而消逝,想着不禁觉得茫茫然。

     其实很早以前,我就一直想做一个小应用,管他几个人用,自己觉得爽就行。或许发展以后就成了潮流的东西,比如Google的“friend connect”,不就一个跨网站的友情链接么?这也是两年前我已经想到的东西,哈哈,YY一下!

     今天的一切,来自昨天的努力;明天的一切,来自今天的努力。

     坚持是一种美德,我一直在想根据现有的人力物力做一个小网站,初步功能已经成型,那就是一个博客导航的网站,地址:http://www.blogread.cn/

      这个小网站说白了,一个网址导航。在这里你可以提交你喜欢的博客,记得不要忘记写上博客的标签(又名“tag”),写上标签,你可以找到与之相似的博客。现在的功能很简单,但是我会一步一步在业余时间逐步增加功能,说不定你下次来,会发现它给了你一个惊喜!

     或许你会觉得界面不太好看,这的确是个郁闷的话题。不着急,美工会一步一步好的。您觉得不爽可以下次再来看看:)

     本不想现在介绍我的博客导航,毕竟还不完善。但是看到一米六二的文章,突然有种冲动就写上以上的文字。

      做事情,是需要激情的,不然会一直拖着,直到消逝而去。

展开全文  
收起全文  
Shell进制运算错误:08: value too great for base (Linux/Unix)
发布于 2008-12-19 12:18 阅读:32786 评论:0 标签: bash shell 进制

      昨天发现一个很奇怪的bug,一个分析log的程序,一个小时产生一个log文件,文件名中含有当时的小时数以作标识,其中小时为有前导零的24 小时格式。bug是第08和09小时的log为空,甚为诧异。

      分析程序后,定位于08和09这两个数字上。程序中有一步需要对小时数进行数学运算,问题就在于此,例如:

以下是代码片段:
[root@login yayu]# echo $((08 -2))
bash: 08: value too great for base (error token is "08")

      Google了一下找到了答案:原文点这![建议新窗口打开]

      原因:

以下是代码片段:
Numbers starting with leading 0 are Octal numbers  (base 8) in many programming
languages including C, Perl and shell. Valid octal digits are
0,1,2,3,4,5,6,7 so it barfs if it sees an 8 or a 9. You probably want
to work in straight numbers and make a leading 0 in your output
format with a sprintf("%02d") kind of formatting thing.
Anything starting with 0x or 0X is a hex number.

So the error message means exactly as it says- it's an error from
the let function complaining about the value being too big for the base.

Have fun,
Stuart.

      解决方案:

以下是代码片段:
You can explicitly state the base of a number using base#number
Code:
if [ $((10#$item)) -eq 0 ] ; then
That will have trouble if the number starts with a minus sign.
The '-' needs to be in front of the base like -10#009 for -9.

      原来是进制的问题,C, Perl 和 shell中以0开头的数字是八进制了,而在运算中也是严格如此,不会做自动转化,于是就报错了。如下解决:

以下是引用片段:
[root@login shengting]# echo $((10#08 -2))
6

      纠结问题的根源,还是我的shell写得太烂了......如果命令用得好就不会遇到这个bug了,不过写得好了,又怎么会在以后避免进制导致的问题呢?到底是先有鸡还是先有蛋呢?

展开全文  
收起全文